【问题标题】:How to make custom UIBarButtonItem with image and label?如何使用图像和标签制作自定义 UIBarButtonItem?
【发布时间】:2013-09-21 14:04:41
【问题描述】:

我想制作一个包含图像和文本的自定义 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;

但是使用这个我只得到图像,而不是标签。我做错了什么?

【问题讨论】:

    标签: ios objective-c ios7


    【解决方案1】:
    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;
    

    【讨论】:

    • 值得注意的是,您可以将图像设置为按钮背景图像属性,这样就无需添加标签,因为您可以改用按钮​​标签。
    • 有什么建议可以在 Interface Builder 中完成吗?我讨厌在代码中包含部分 UI,而在 IB 中包含部分。
    • @oarfish 用代码编写所有内容 - 问题已解决 :D 大多数高级开发人员都会这样做。
    • 无法使用这种方法将 tintColor 设置为按钮,关于设置 tintColor 有什么想法吗?
    【解决方案2】:
    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);
    

    然后将该按钮设为您的自定义栏按钮

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

    【讨论】:

      【解决方案3】:

      您可以向UIBarButtonItem 添加自定义视图。

      在 iOS 7 中,有一个名为 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;
      

      更新了 Swift 代码,

      let leftButtonView = UIView.init(frame: CGRect(x: 0, y: 0, width: 110, height: 50))
      
      let leftButton = UIButton.init(type: .system)
      leftButton.backgroundColor = .clear
      leftButton.frame = leftButtonView.frame
      leftButton.setImage(UIImage.init(imageLiteralResourceName: <YourImageName>), for: .normal)
      leftButton.setTitle("YourTitle", for: .normal)
      leftButton.tintColor = .red //Your desired color.
      leftButton.autoresizesSubviews = true
      leftButton.autoresizingMask = [.flexibleWidth , .flexibleHeight]
      leftButton.addTarget(self, action: #selector(<YourTargetMethod>), for: .touchUpInside)
      leftButtonView.addSubview(leftButton)
      
      let leftBarButton = UIBarButtonItem.init(customView: leftButtonView)
      navigationItem.leftBarButtonItem = leftBarButton
      

      【讨论】:

      • 问题是,图像的尺寸应该是多少才能看起来与原生背景图像完全一样? (我想创建自己的自定义后退按钮,以便控制其事件...)
      • 这在分配时有效:“self.navigationItem.leftBarButtonItem = leftBarButton;”但是当将它分配给 UIBarbuttonItem 时它不会像“self.boto_icona_client = leftBarButton;”知道为什么吗?
      【解决方案4】:

      接受答案的问题是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];
      

      【讨论】:

        【解决方案5】:

        如果您的 BarButtonItem 在 Storyboard 中,您可以将另一个 Button 拖到 BarButtonItem 中,这样 BarButtonItem 内就会有一个 Button,您可以为该按钮添加图像和标签。

        【讨论】:

        • 确认这在 iOS7 和 iOS8 中都有效。
        • iOS13 的 Storyboard 中不能将 BarButtonItems 的高度调整为低于 44p。必须以编程方式完成。
        【解决方案6】:

        我在这里发布了处理与普通 uibarbuttonitem 相似的色调颜色和图像的答案...https://stackoverflow.com/a/28348461/925135

        【讨论】:

          【解决方案7】:

          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];
          

          【讨论】:

            【解决方案8】:

            在 UIBarButtonItem 中使用 UIButton 作为自定义视图。您可以使用-setImage:forState:-setTitle:forState: 随心所欲地创建UIButton,包括图像和文本

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

            这可以使用界面生成器完成,只需将 UIButton 拖到导航栏上的左侧栏按钮槽即可。

            【讨论】:

              【解决方案9】:

              SWIFT 版本

                  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
              

              【讨论】:

                【解决方案10】:

                这是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
                

                【讨论】:

                  【解决方案11】:

                  这是我基于之前答案的解决方案。可能会有帮助。

                  extension UIBarButtonItem {
                      static func button(image: UIImage, title: String, target: Any, action: Selector) -> UIBarButtonItem {
                          let button = UIButton()
                          button.setImage(image, for: .normal)
                          button.addTarget(target, action: action, for: .touchUpInside)
                          button.setTitle(title, for: .normal)
                          button.sizeToFit()
                          return UIBarButtonItem(customView: button)
                      }
                  }
                  

                  【讨论】:

                  • 如何设置标题左侧而不是右侧?
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-03-08
                  • 1970-01-01
                  • 2021-07-08
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多