Как сделать пользовательский UIBarButtonItem с изображением и меткой?


Я хотел бы сделать пользовательский UIBarButtonItem, который содержит как изображение, так и текст, что-то вроде этого:

Я попытался подкласс UIBarButtonItem и переопределение этого метода:

- (UIView *)customView
{
    if (!self.storedView) {

        UIView *temp = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 44)];
        UIImageView *tempImageView = [[UIImageView alloc] initWithImage:self.image];
        tempImageView.frame = CGRectMake(0, 0, self.image.size.width, self.image.size.height);
        UILabel *tempLabel = [[UILabel alloc] initWithFrame:CGRectMake(44, 0, 100, 44)];
        tempLabel.text = @"text";
        [temp addSubview:tempImageView];
        [temp addSubview:tempLabel];
        self.storedView = temp;
    }
    return self.storedView;
}

и я использую его так:

UIBarButtonItem *left = [[LeftItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStylePlain target:self action:@selector(settingsPressed)];
left.title = @"Settings";
left.image = [UIImage imageNamed:@"settings.png"];
self.navigationItem.leftBarButtonItem = left;

но с помощью этого я получаю только изображение, но не ярлык. Что я делаю не так?

11 59

11 ответов:

UIButton *button =  [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
[button addTarget:target action:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 53, 31)];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(3, 5, 50, 20)];
[label setFont:[UIFont fontWithName:@"Arial-BoldMT" size:13]];
[label setText:title];
label.textAlignment = UITextAlignmentCenter;
[label setTextColor:[UIColor whiteColor]];
[label setBackgroundColor:[UIColor clearColor]];
[button addSubview:label];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = barButton;

вы можете добавить пользовательский вид в UIBarButtonItem.

в iOS 7, есть новый buttonType называется UIButtonTypeSystem на UIButton, которые служат вашим целям. Попробуй это,

UIView* leftButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 110, 50)];

UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
leftButton.backgroundColor = [UIColor clearColor];
leftButton.frame = leftButtonView.frame;
[leftButton setImage:[UIImage imageNamed:<YourImageName>] forState:UIControlStateNormal];
[leftButton setTitle:@"YourTitle" forState:UIControlStateNormal];
leftButton.tintColor = [UIColor redColor]; //Your desired color.
leftButton.autoresizesSubviews = YES;
leftButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;
[leftButton addTarget:self action:@selector(<YourTargetMethod>) forControlEvents:UIControlEventTouchUpInside];
[leftButtonView addSubview:leftButton];

UIBarButtonItem* leftBarButton = [[UIBarButtonItem alloc]initWithCustomView:leftButtonView];
self.navigationItem.leftBarButtonItem = leftBarButton;

Если ваш BarButtonItem находится в раскадровке, вы можете перетащить другую кнопку в BarButtonItem, поэтому внутри BarButtonItem будет кнопка, вы можете добавить как изображение, так и метку к кнопке.

быстрая версия

    let button =  UIButton(type: .Custom)
    button.setImage(UIImage(named: "icon_right"), forState: .Normal)
        button.addTarget(self, action: "buttonAction", forControlEvents: .TouchUpInside)
    button.frame = CGRectMake(0, 0, 53, 31)
    button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32)//move image to the right
    let label = UILabel(frame: CGRectMake(3, 5, 50, 20))
    label.font = UIFont(name: "Arial-BoldMT", size: 16)
    label.text = "title"
    label.textAlignment = .Center
    label.textColor = UIColor.whiteColor()
    label.backgroundColor =   UIColor.clearColor()
    button.addSubview(label)
    let barButton = UIBarButtonItem(customView: button)
    self.navigationItem.rightBarButtonItem = barButton

проблема с принятым ответом заключается в том, что UIBarButtonItem текст не изменяется при выделении. Код ниже будет отображать текст плюс изображение. Элемент UIEdgeInsetsMake перемещение текста влево и изображения вправо.

UIButton *button =  [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(myButtonEvent:) 
             forControlEvents:UIControlEventTouchUpInside];
[button setFrame:CGRectMake(0, 0, 53, 32)];

[button setTitle:title forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] 
                 forState:UIControlStateNormal];
[button setTitleColor:[UIColor lightGrayColor] 
                 forState:UIControlStateHighlighted];
button.titleEdgeInsets = UIEdgeInsetsMake(-2, -20, 2, 20);
button.titleLabel.font = font;
button.titleLabel.textAlignment = NSTextAlignmentLeft;

UIImage *image = [UIImage imageNamed:@"imageName"];
[button setImage:image 
        forState:UIControlStateNormal];
button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32);
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];

Я опубликовал ответ, который обрабатывает оттенок цвета и изображение, аналогичное нормальному uibarbuttonitem здесь... https://stackoverflow.com/a/28348461/925135

другой подход с NSAttributedString:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Button Text"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"buttonImage"];
textAttachment.bounds = CGRectMake(0, -3, textAttachment.image.size.width, textAttachment.image.size.height); //the origin y value depends on the size of the image to get a perfect fit
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedString replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attrStringWithImage]; // Adding the image at the beginning
[customButton setAttributedTitle:attributedString forState:UIControlStateNormal];
[customButton sizeToFit];
[customButton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithCustomView:customButton];

использование UIButton в качестве пользовательского представления внутри вашего UIBarButtonItem. Вы можете создать UIButton, как вы хотите, в том числе с изображением и текстом, используя -setImage:forState: и -setTitle:forState:

UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:@"settings.png"] forState:UIControlStateNormal];
[button setTitle:@"Settings" forState:UIControlStateNormal];
[button addTarget:target action:@selector(buttonAction:)forControlEvents:UIControlEventTouchUpInside];
[button sizeToFit];
UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = barButtonItem;

Это можно сделать с помощью interface builder, просто перетащив UIButton в слот кнопки левой панели на панели навигации.

UIImage *image = [UIImage imageNamed:@"icon.png"];
UIImage *backgroundSelected = [UIImage imageNamed:@"icon_selected.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(ButtonTapped:event:)forControlEvents:UIControlEventTouchUpInside]; //adding action
[button setBackgroundImage:image forState:UIControlStateNormal];
[button setBackgroundImage:backgroundSelected forState:UIControlStateSelected];
button.frame = CGRectMake(0 ,0,35,35);

затем сделать эту кнопку в качестве пользовательского barbutton

UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = barButton;

Это обновленная версия ответа ripegooseberry для Swift 3

    let button =  UIButton(type: .custom)
    button.setImage(UIImage(named: "icon_right"), for: .normal)
    button.addTarget(self, action: Selector(("buttonAction")), for: .touchUpInside)
    button.frame = CGRect(x: 0, y: 0, width: 53, height: 31)
    button.imageEdgeInsets = UIEdgeInsetsMake(-1, 32, 1, -32)//move image to the right
    let label = UILabel(frame: CGRect(x: 3, y: 5, width: 50, height: 20))
    label.font = UIFont(name: "Arial-BoldMT", size: 16)
    label.text = "title"
    label.textAlignment = .center
    label.textColor = UIColor.white
    label.backgroundColor =   UIColor.clear
    button.addSubview(label)
    let barButton = UIBarButtonItem(customView: button)
    self.navigationItem.rightBarButtonItem = barButton

потрясающее решение! Я искал, чтобы добавить UISlider в UIToolbar, и я сделал это именно так! Не забудьте добавить целевое действие для ваших пользовательских кнопок с помощью:

  customButton.targetForAction(#selector(addTapped), withSender: self)

таким образом, вы можете управлять своими кнопками:)