【问题标题】:UIButton title and image alignment queryUIButton标题和图片对齐查询
【发布时间】:2009-07-12 14:24:35
【问题描述】:

我有一个UIButton,我正在尝试在上面设置标题和图片。

我想将UIButton 的标题与左侧对齐,并将图像与右侧对齐。我正在尝试获取时钟应用程序中计时器中按钮的外观和感觉(显示“计时器结束时”的按钮)。

我摆弄contentHorizontalAlignment、contentEdgeInsets、titleEdgeInsets 和imageEdgeInsets 来实现我的目标,但无济于事。同样的文档也很少。

我怎样才能达到同样的效果?

还有相关的问题,时钟应用程序中的计时器有两组文本,一组与图像左对齐,另一组右对齐?如何在UIButton 中做到这一点? (虽然目前我不需要该功能)。

【问题讨论】:

    标签: iphone cocoa-touch uibutton


    【解决方案1】:

    这是我使用的代码:

    //Right-align the button image
    CGSize size = [[myButton titleForState:UIControlStateNormal] sizeWithFont:myButton.titleLabel.font];
    [myButton setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, -size.width)];
    [myButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, myButton.imageView.image.size.width + 5)];
    

    【讨论】:

    • 这是 IMO 一个更好的,如果有点过于简洁,使用代码回答与@Bill 的最高投票答案相比,它告诉您使用这些 API 调用但不显示调用它们。如果它显示调用 setImage:forState: 会更好。此外,我发现在某些情况下,比如 actionSheets,一旦你设置了 setImageEdgeInsets,你就不需要调整 titleEdgeInsets——它们已经考虑了你的图像宽度。 YMMV。
    • 如果您将contentHorizontalAlignment 设置为UIControlContentHorizontalAlignmentRight,您还需要在titleEdgeInsets 的左侧添加一个插图。这是:[myButton setTitleEdgeInsets:UIEdgeInsetsMake(0, -imageSize.width, 0, imageSize.width)];
    【解决方案2】:

    更改UIButton 上的imageEdgeInsets 属性,然后只使用setImage:forState:

    【讨论】:

    • 如果您使用的是 UIButton,这是正确的方法。表视图是另一种野兽。
    • 同意,但 OP 没有提到表格视图 :)
    【解决方案3】:

    以下代码有效:

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = buttonRect;
    [button setTitle:@"A title" forState:UIControlStateNormal];
    [button setImage:buttonImage forState:UIControlStateNormal];
    button.imageEdgeInsets = UIEdgeInsetsMake(0.0, WIDTH(button.titleLabel) + 10.0, 0.0, 0.0);
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    

    【讨论】:

      【解决方案4】:

      请记住,UIButton 继承自 UIView,因此您可以像添加任何其他视图一样向其添加子视图。在您的情况下,您将创建一个按钮,然后在左侧添加一个 UILabel 并在右侧添加一个 UIImage:

      // Create the button
      UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
      
      // Now load the image and create the image view
      UIImage *image = [UIImage imageNamed:@"yourImage.png"];
      UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(/*frame*/)];
      [imageView setImage:image];
      
      // Create the label and set its text
      UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(/*frame*/)];
      [label setText:@"Your title"];
      
      // Put it all together
      [button addSubview:label];
      [button addSubview:imageView];

      【讨论】:

      • 这似乎不太好用。我在按钮上有一个背景图像,如果我设置背景图像,则标签不可见。如果我从按钮中删除背景图像,标签变得可见?我将标签添加到 UIButton 的父视图并对齐到 UIButton 的顶部,然后它就可以工作了。知道为什么会这样吗?
      • 当背景图像作为 UIButton 的子视图添加到自定义视图之上时,通常会出现这种行为。与其设置按钮的 backgroundImage 属性,不如考虑自己为背景图像添加一个 UIImageView,然后在该图像视图之上添加其他自定义内容。
      • 无需滚动您自己的逻辑 - 使用 UIButton 和 setImage:forState: 上的 imageEdgeInsets 属性。
      • OP 专门说:“我摆弄了 ...imageEdgeInsets 以实现我的目标,但无济于事。”
      • 这个答案建议在按钮内创建一个新的UIImageView,该按钮已经有一个。它确实有效,但推荐的解决方案将涉及imageRectForContentRect: 和titleRectForContentRect:,它们是为此目的而明确提供的。
      【解决方案5】:

      您还可以覆盖UIButton 的titleRectForContentRect: 和imageRectForContentRect: 方法,以便将您的文本和图像放置在您想要的任何位置。

      【讨论】:

        【解决方案6】:

        在 Swift 中适合任何关心的人(间距为 10pt):

        let size = (self.titleForState(UIControlState.Normal)! as NSString).sizeWithAttributes([NSFontAttributeName:self.titleLabel!.font])
        let offset = (size.width + 10)
        self.imageEdgeInsets = UIEdgeInsetsMake(0, offset, 0, -offset)
        self.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, self.imageView!.frame.size.width + 10)
        

        【讨论】:

          【解决方案7】:

          为了在 iOS 9 上使用,我在这个帖子中尝试了很多答案,但没有一个适合我。我为自己找到了如下答案:

          class MyButton: UIButton {
          
            override func layoutSubviews() {
              super.layoutSubviews()
          
              self.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
          
              if self.imageView?.image != nil {
                // Move icon to right side
                self.imageEdgeInsets = UIEdgeInsets(
                  top: 0,
                  left: self.bounds.size.width - self.imageView!.image!.size.width,
                  bottom: 0,
                  right: 0)
          
                // Move title to left side
                self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView!.frame.size.width + 8, 0, 0)
          
              }
            }
          }
          

          SWIFT 3:

          class MyButton: UIButton {
          
              override func layoutSubviews() {
                  super.layoutSubviews()
          
                  self.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left
          
                  if self.imageView?.image != nil {
                      // Move icon to right side
                      self.imageEdgeInsets = UIEdgeInsets(
                          top: 0,
                          left: self.bounds.size.width - self.imageView!.image!.size.width,
                          bottom: 0,
                          right: 0)
          
                      // Move title to left side
                      self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView!.frame.size.width + 8, 0, 0)
          
                  }
              }
          }
          

          我希望它能帮助像我这样的人!

          【讨论】:

          • 干得好,我用 Swift 3 更新你
          【解决方案8】:

          这是 Swift 中UIButton 的一个子类,它将左侧的图像和中间的文本对齐。将imageLeftInset 设置为您想要的值。

          class LeftImageAlignedButton : UIButton {
          
          var imageLeftInset : CGFloat = 10.0
          
          override func layoutSubviews() {
              super.layoutSubviews()
              self.contentHorizontalAlignment = .Left
              if let font = titleLabel?.font {
                  let textWidth = ((titleForState(state) ?? "") as NSString).sizeWithAttributes([NSFontAttributeName:font]).width
                  let imageWidth = imageForState(state)?.size.width ?? 0.0
                  imageEdgeInsets = UIEdgeInsets(top: 0, left: imageLeftInset, bottom: 0, right: 0)
                  titleEdgeInsets = UIEdgeInsets(top: 0, left: bounds.width/2 - textWidth/2.0 - imageWidth, bottom: 0, right: 0)
              }
          }
          }
          

          【讨论】:

            【解决方案9】:

            创建一个 UIButton 子类并覆盖它的layoutSubviews 方法,以编程方式对齐您的文本和图像。或者使用 https://github.com/stevestreza/BlockKit/blob/master/Source/UIView-BKAdditions.h 之类的东西,这样您就可以使用块来实现 layoutSubviews。

            【讨论】:

            • 没问题,虽然我不确定使用这种机制与普通子类化相比是否值得。
            • 虽然这对于一般视图来说是一个很好的策略,但-(CGRect) imageRectForContentRect:(CGRect)contentRect 和-(CGRect) titleRectForContentRect:(CGRect)contentRect 明确用于此目的。不幸的是,每次更改视图布局时都会调用layoutSubviews,因此在这种情况下不适合。
            • 但我敢打赌imageRectForContentRect: 等。也被称为布局 - 我想知道为什么你认为“这种情况”使它不合适?除此之外,layoutSubviews 让您可以一次性完全控制布局,这也很好。我想这取决于 - IIRC 正确我在制作带有顶部对齐图标和底部对齐文本的按钮时遇到了一些麻烦(使用 ...forContentRect)。
            猜你喜欢
            • 1970-01-01
            • 2013-03-06
            • 1970-01-01
            • 2010-10-31
            • 1970-01-01
            • 2016-07-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多