【问题标题】:Left-align image and center text on UIButtonUIButton 上的左对齐图像和居中文本
【发布时间】:2012-06-12 20:51:36
【问题描述】:

我看过关于右对齐的帖子,但我无法让左对齐工作。我希望按钮占据屏幕的宽度,图像在左侧,标题/文本在中间。

这不起作用(至少可靠):

    button.titleLabel.textAlignment = UITextAlignmentCenter;
    [button setImageEdgeInsets:UIEdgeInsetsMake(0, -60.0, 0, 0)];
    button.frame = CGRectMake((self.view.frame.size.width - w ) / 2, self.view.frame.size.height - 140.0,  self.view.frame.size.width - 10.0, 40.0);

【问题讨论】:

    标签: ios uiimage uibutton


    【解决方案1】:

    此解决方案适用于 Swift 3,并尊重原始内容和图像边缘插入,同时保持标题标签始终位于可用空间的中心,这使得调整边距变得更加容易。

    它覆盖titleRect(forContentRect:) 方法并返回正确的帧:

    @IBDesignable
    class LeftAlignedIconButton: UIButton {
        override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
            let titleRect = super.titleRect(forContentRect: contentRect)
            let imageSize = currentImage?.size ?? .zero
            let availableWidth = contentRect.width - imageEdgeInsets.right - imageSize.width - titleRect.width
            return titleRect.offsetBy(dx: round(availableWidth / 2), dy: 0)
        }
    }
    

    以下插图:

    会导致:


    不推荐使用之前的答案

    这在大多数情况下都有效,但某些布局会导致layoutSubviews 在无限循环中递归调用自身,因此谨慎使用

    @IBDesignable
    class LeftAlignedIconButton: UIButton {
        override func layoutSubviews() {
            super.layoutSubviews()
            contentHorizontalAlignment = .left
            let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets)
            let availableWidth = availableSpace.width - imageEdgeInsets.right - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
            titleEdgeInsets = UIEdgeInsets(top: 0, left: availableWidth / 2, bottom: 0, right: 0)
        }
    }
    

    此代码将执行相同的操作,但将图标与右边缘对齐:

    @IBDesignable
    class RightAlignedIconButton: UIButton {
        override func layoutSubviews() {
            super.layoutSubviews()
            semanticContentAttribute = .forceRightToLeft
            contentHorizontalAlignment = .right
            let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets)
            let availableWidth = availableSpace.width - imageEdgeInsets.left - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
            titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: availableWidth / 2)
        }
    }
    

    正确的对齐版本使用semanticContentAttribute,所以它需要iOS 9+。

    【讨论】:

    • 我相信 frame.width 应该是 frame.size.width
    • 您必须设置contentHorizontalAlignment = .left 才能使其工作。
    • 在最后一行:return titleRect.offsetBy(...) 我不得不改变从父矩形移动标题矩形:return contentRect.offsetBy(...)
    • 你拯救了我的一天。
    【解决方案2】:

    最后,我使用 UIEdgeInsetsMake 执行此操作,计算左角以使其居中。我不确定是否真的可以使文本居中对齐,但这对我有用。确保通过计算宽度将左角设置为所需位置。例如UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f)

    UIButton *scanBarCodeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    scanBarCodeButton.frame = CGRectMake(center, 10.0f, fieldWidth, 40.0f);
    [scanBarCodeButton setImage:[UIImage imageNamed:@"BarCodeIcon.png"] forState:UIControlStateNormal];
    [scanBarCodeButton setTitle:@"Scan the Barcode" forState:UIControlStateNormal];
    scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, 42.0f, 0.0f, 0.0f);
    [scanBarCodeButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
    [scanBarCodeButton addTarget:self action:@selector(scanBarCode:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:scanBarCodeButton];
    

    输出看起来像,

    Swift 中:

    var scanBarCodeButton: UIButton = UIButton(type: .roundedRect)
    scanBarCodeButton.frame = CGRectMake(center, 10.0, fieldWidth, 40.0)
    scanBarCodeButton.setImage(UIImage(named: "BarCodeIcon.png"), for: UIControlStateNormal)
    scanBarCodeButton.setTitle("Scan the Barcode", for: UIControlStateNormal)
    scanBarCodeButton.titleEdgeInsets = UIEdgeInsetsMake(0.0, 42.0, 0.0, 0.0)
    scanBarCodeButton.contentHorizontalAlignment = .left
    scanBarCodeButton.addTarget(self, action: "scanBarCode:", for: UIControlEventTouchUpInside)
    self.view.addSubview(scanBarCodeButton)
    

    【讨论】:

    • 谢谢!正是我想要的。
    • 对我来说,这里的要点是将内容水平对齐设置为左对齐,而不是默认居中。文本本身仍位于文本区域的中心。您的幻数“42”是图像的宽度,很容易计算。
    • googlebtn.imageEdgeInsets = UIEdgeInsets(上:0.0,左:-20.0,下:0.0,右:0.0);
    【解决方案3】:

    对于 Swift 4.0,这是一个有效的扩展-

    extension UIButton {
    
      func leftImage(image: UIImage, renderMode: UIImage.RenderingMode) {
           self.setImage(image.withRenderingMode(renderMode), for: .normal)
           self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
           self.titleEdgeInsets.left = (self.frame.width/2) - (self.titleLabel?.frame.width ?? 0)
           self.contentHorizontalAlignment = .left
           self.imageView?.contentMode = .scaleAspectFit
       }
        
        func rightImage(image: UIImage, renderMode: UIImageRenderingMode){
            self.setImage(image.withRenderingMode(renderMode), for: .normal)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left:image.size.width / 2, bottom: 0, right: 0)
            self.contentHorizontalAlignment = .right
            self.imageView?.contentMode = .scaleAspectFit
        }
    }
    

    用法:

    myButton.rightImage(image: UIImage(named: "image_name")!, renderMode: .alwaysOriginal)
    myButton.leftImage(image: UIImage(named: "image_name")!, renderMode: .alwaysOriginal)
    

    renderMode 可以是.alwaysTemplate.alwaysOriginal。此外,myButton 应该是 custom 类型 UIButton

    此扩展的leftImagerightImage 也可以用于UIButton 中的UIBarButtonItem 中的UINavigationBar(注意:从iOS 11 开始,导航栏遵循自动布局,因此您需要添加宽度/高度UIBarButtonItem) 的约束。要在导航栏上使用,请确保遵循 Apple 推荐的 @2x 和 @3x 图像尺寸(即 50x50、75x75)并在 iPhone 6、7、8、6s、7s、8s、Plus 变体和 iPhone 上获得更好的可访问性x UIBarButton 的宽度和高度可以是高度 - 25 和宽度 - 55(或者您的应用需要的任何值,这些数字是适用于大多数情况的基本数字)。


    更新:在 Swift 4.2 中,UIImageRenderingMode 已重命名为 UIImage.RenderingMode

    extension UIButton {
        func leftImage(image: UIImage, renderMode: UIImage.RenderingMode) {
            self.setImage(image.withRenderingMode(renderMode), for: .normal)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width / 2)
            self.contentHorizontalAlignment = .left
            self.imageView?.contentMode = .scaleAspectFit
        }
        
        func rightImage(image: UIImage, renderMode: UIImage.RenderingMode){
            self.setImage(image.withRenderingMode(renderMode), for: .normal)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left:image.size.width / 2, bottom: 0, right: 0)
            self.contentHorizontalAlignment = .right
            self.imageView?.contentMode = .scaleAspectFit
        }
    }
    

    【讨论】:

    • 此解决方案必须添加以下代码。让 rightInset = (image.size.width / 2) + 10 self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: rightInset)
    • 不起作用。标题对齐未在按钮中居中,这是 OP 想要的。
    • 标题的对齐方式是相对于正在使用的图像,所以当然标题不会相对于按钮宽度居中。如果您将标签相对于按钮宽度居中,则某些标题可能会与图像重叠,具体取决于标题的长度。
    【解决方案4】:

    我已经尝试了上述几乎所有解决方案,但都没有按我的预期工作(我有两个按钮,每个按钮都有不同的标题和不同的图像宽度)。所以我为 UIButton 编写了自己的扩展,它可以完美地与不同的图像宽度以及不同的标题一起工作。

    extension UIButton {
        func moveImageLeftTextCenter(imagePadding: CGFloat = 30.0, titlePadding: CGFloat = 0.0, minImageTitleDistance: CGFloat = 10.0){
        guard let imageViewWidth = imageView?.frame.width else{return}
        guard let titleLabelWidth = titleLabel?.intrinsicContentSize.width else{return}
        contentHorizontalAlignment = .left
    
        let imageLeftInset = imagePadding - imageViewWidth / 2
        var titleLeftInset = (bounds.width - titleLabelWidth) / 2 - imageViewWidth + titlePadding
    
        if titleLeftInset - imageLeftInset < minImageTitleDistance{
            titleLeftInset = imageLeftInset + minImageTitleDistance
        }
    
        imageEdgeInsets = UIEdgeInsets(top: 0.0, left: imageLeftInset, bottom: 0.0, right: 0.0)
        titleEdgeInsets = UIEdgeInsets(top: 0.0, left: titleLeftInset, bottom: 0.0, right: 0.0)
        }
    }
    

    用法:myButton.moveImageLeftTextCenter()

    【讨论】:

      【解决方案5】:

      我认为,好的解决方案必须对任何文本都有用,没有硬编码的插入值(这是关于 toytoy 提供的解决方案)。我使用类似这样的代码:

      NSString *sometitle = @"blabla button title";
      NSString *someimage = @"blablaimage";
      UIImage *image = [[UIImage imageNamed:someimage];
      int buttonWidth = A;
      int buttonHeight = B;
      int imageWidth =image.size.width;
      int imageHeight = image.size.height;
      int titleWidth = buttonWidth - imageWidth;
      
      // create button and set image and title
      buttonView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonWidth, buttonHeight)];
      [buttonView setImage:image forState:UIControlStateNormal];
      [buttonView setTitle:sometitle forState:UIControlStateNormal];
      
      // make button all content to be left aligned
      [buttonView setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
      
      // set title font 
      [buttonView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:14]];
      
      // calculate font text width with selected font
      CGSize stringBoundingBox = [number sizeWithFont:[buttonView.titleLabel font]];
      
      // make title inset with some value from left 
      // it place the title right on the center of space for the title
      int titleLeft = (titleWidth - stringBoundingBox.width) / 2;
      [buttonView setTitleEdgeInsets:UIEdgeInsetsMake(0, titleLeft, 0, 0)];
      

      在带有 stringBoundingBox init 的字符串之后,我还添加了一些这样的字符串:

      if (stringBoundingBox.width > titleWidth)
      {
          [_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:13]];
          stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]];
      }
      if (stringBoundingBox.width > titleWidth)
      {
          [_backgroundView.titleLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:12]];
          stringBoundingBox = [number sizeWithFont:[_backgroundView.titleLabel font]];
      }
      

      它允许我通过选择一些较小的字体来设置比可用空间更长的标题。我这样做是因为另一种方式:

      [buttonView.titleLabel setAdjustsFontSizeToFitWidth:YES];
      

      效果不太好,好像一步把字体大小缩小了3-4个点,所以一些不太长的线条变得太小了,比它必须的要小。

      此代码允许我们将按钮标题空间中的任何文本准确地放在中心。

      【讨论】:

        【解决方案6】:

        我写了一个 UIButton 扩展。

        extension UIButton {
        
          /// Add image on left view
          func leftImage(image: UIImage) {
            self.setImage(image, for: .normal)
            self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: image.size.width)
          }
        }
        

        你可以这样使用:

        yourButton.leftImage(image: yourImage)
        

        瞧!

        【讨论】:

          【解决方案7】:

          创建您的按钮并将文本对齐设置为居中,然后添加:

          UIImage *image = [UIImage imageNamed:@"..."];
          CGSize imageSize = image.size;
          CGFloat offsetY = floor((self.layer.bounds.size.height - imageSize.height) / 2.0);
          
          CALayer *imageLayer = [CALayer layer];
          imageLayer.contents = (__bridge id) image.CGImage;
          imageLayer.contentsGravity = kCAGravityBottom;
          imageLayer.contentsScale = [UIScreen mainScreen].scale;
          imageLayer.frame = CGRectMake(offsetY, offsetY, imageSize.width, imageSize.height);
          [self.layer addSublayer:imageLayer];
          

          【讨论】:

            【解决方案8】:
            [self.button setImage:[UIImage imageNamed:@"image.png"] forState:UIControlStateNormal];
            
            [self.button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, self.button.center.x/2 , 0.0, 0.0)];
            
            [self.button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
            

            如果它不起作用,请告诉我。

            我的输出

            【讨论】:

            • 文字不居中,被图片推到右边
            • 然后你可以改变 UIEdgeInsetsMake 的值。试试看吧。
            【解决方案9】:

            尝试了大多数答案,但没有运气。我大部分时间都得到蓝色图像,或者标题不在中心。使用了一些答案中的代码并编写了这个扩展,就像一个魅力。

            斯威夫特 4.2:

            import UIKit
            
            extension UIButton {
                func moveImageLeftTextCenter(image : UIImage, imagePadding: CGFloat, renderingMode: UIImage.RenderingMode){
                    self.setImage(image.withRenderingMode(renderingMode), for: .normal)
                    guard let imageViewWidth = self.imageView?.frame.width else{return}
                    guard let titleLabelWidth = self.titleLabel?.intrinsicContentSize.width else{return}
                    self.contentHorizontalAlignment = .left
                    let imageLeft = imagePadding - imageViewWidth / 2
                    let titleLeft = (bounds.width - titleLabelWidth) / 2 - imageViewWidth
                    imageEdgeInsets = UIEdgeInsets(top: 0.0, left: imageLeft, bottom: 0.0, right: 0.0)
                    titleEdgeInsets = UIEdgeInsets(top: 0.0, left: titleLeft , bottom: 0.0, right: 0.0)
                }
            }
            

            希望对大家有所帮助!

            【讨论】:

              【解决方案10】:

              这对我来说效果很好,适用于几个按钮,具有不同的图像宽度和不同的标题长度:

              子类UIButton,并添加如下方法:

              override func layoutSubviews() {
                  super.layoutSubviews()
              
                  if let image = imageView?.image {
              
                      let margin = 30 - image.size.width / 2
                      let titleRect = titleRectForContentRect(bounds)
                      let titleOffset = (bounds.width - titleRect.width - image.size.width - margin) / 2
              
              
                      contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
                          imageEdgeInsets = UIEdgeInsetsMake(0, margin, 0, 0)
                          titleEdgeInsets = UIEdgeInsetsMake(0, (bounds.width - titleRect.width -  image.size.width - margin) / 2, 0, 0)
                  }
              
              }
              

              【讨论】:

              • @JefferyThomas 这只是一个余量。使用这种方法,它适用于不同图像大小的我。
              【解决方案11】:

              我用 swift 写了一个 UIButton 扩展 -

              extension UIButton {
              
              func setLeftImage(imageName:String, padding:CGFloat) {
                      //Set left image
                      let image = UIImage(named: imageName)
                      self.setImage(image, forState: .Normal)
              
                      //Calculate and set image inset to keep it left aligned
                      let imageWidth = image?.size.width
                      let textWidth = self.titleLabel?.intrinsicContentSize().width
                      let buttonWidth = CGRectGetWidth(self.bounds)
              
                      let padding:CGFloat = 30.0
                      let rightInset = buttonWidth - imageWidth!  - textWidth! - padding
              
                      self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: rightInset)
                  }
              }
              

              我会以任何我想要的方式设置按钮文本的样式,并保持居中对齐。 然后我会在我的按钮上调用这个方法,比如 -

              myButton.setLeftImage("image_name", 30.0)
              

              这将导致我的图像与左边框的一些填充左对齐。

              【讨论】:

              • 您有一个参数作为“填充”,并在函数中实例化了一个值,称为“填充”。这会覆盖参数函数,应该在使用前进行优化。
              【解决方案12】:

              1) button.frame = self.view.bounds;

              2) setImageEdgeInsets 带有负值,当你的按钮填满屏幕时,这是疯狂的。重新考虑您要在这里做什么?

              3) UITextAlignmentCenter 现在是 NSTextAlignmentCenter

              4)button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

              【讨论】:

                【解决方案13】:

                我在这里看到了很多专注于将图标设置在左侧的解决方案。我认为只需添加一个 UIImageView、将按钮的左侧和图像对齐并将它们居中对齐会更容易。然后你可以稍微调整一下偏移量,让它看起来不错。

                无需代码,全部在 Interface Builder 中。

                【讨论】:

                • 是的,但是该图像会响应用户的触摸,例如颜色变化吗?
                • 您可以在所有图像上使用 tint color 但默认情况下不启用:stackoverflow.com/questions/22170688/…
                • 我猜你是对的。因此,您建议应用程序应覆盖 setSelected() 方法并手动维护图像外观(不是默认行为)。
                【解决方案14】:

                我知道这个答案有点晚了。 但是对于想要使用 UIImageView 在带有居中文本的 UIButton 左侧添加图像的人们,我有一个非常简单的解决方案。全部以编程方式

                class RandomVC: UIViewController{
                
                    var imageDemo: UIImageView = {
                    let img = UIImageView()
                    img.translatesAutoresizingMaskIntoConstraints = false
                    img.image = UIImage(named: "someImgFromAssets")
                    return img
                    }()
                
                    lazy var someButton: UIButton = { //lazy var: so button can have access to self class
                    let button = UIButton(type: .system)
                    button.setTitle("This is your title", for: UIControlState.normal)
                    button.translatesAutoresizingMaskIntoConstraints = false 
                    button.setTitleColor(UIColor.white, for: UIControlState.normal)
                    button.addTarget(self, action: #selector(handleButtonClick), for: .touchUpInside) //make sure you write function "handleButtonClick" inside your class
                    button.titleLabel?.textAlignment = .center
                    return button
                    }()
                
                    override func viewDidLoad() {
                        super.viewDidLoad()
                        view.addSubView(someButton)
                        someButton.addSubview(imageDemo)
                        imageDemo.centerYAnchor.constraint(equalTo: someButton.centerYAnchor).isActive = true
                        imageDemo.leftAnchor.constraint(equalTo: someButton.leftAnchor, constant: 10).isActive = true
                        imageDemo.heightAnchor.constraint(equalToConstant: 25).isActive = true
                        imageDemo.widthAnchor.constraint(equalToConstant: 25).isActive = true
                    }
                
                }
                

                【讨论】:

                  【解决方案15】:

                  以下扩展适用于我在 Swift 4.2 中

                  func leftImage(image: UIImage, padding: CGFloat, renderMode: UIImage.RenderingMode) {
                      self.setImage(image.withRenderingMode(renderMode), for: .normal)
                      contentHorizontalAlignment = .left
                      let availableSpace = bounds.inset(by: contentEdgeInsets)
                      let availableWidth = availableSpace.width - imageEdgeInsets.right - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
                      titleEdgeInsets = UIEdgeInsets(top: 0, left: availableWidth / 2, bottom: 0, right: 0)
                      imageEdgeInsets = UIEdgeInsets(top: 0, left: padding, bottom: 0, right: 0)
                  }
                  
                  func rightImage(image: UIImage, padding: CGFloat, renderMode: UIImage.RenderingMode){
                      self.setImage(image.withRenderingMode(renderMode), for: .normal)
                      semanticContentAttribute = .forceRightToLeft
                      contentHorizontalAlignment = .right
                      let availableSpace = bounds.inset(by: contentEdgeInsets)
                      let availableWidth = availableSpace.width - imageEdgeInsets.left - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0)
                      titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: availableWidth / 2)
                      imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: padding)
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    我的 SWIFT 5.2 解决方案。

                    你必须继承 UIButton 类。无需像其他人在其他答案中所做的那样更改内容水平对齐方式,将其保持为“中心”(.center)。标题会自动居中,而 imageRect() 的覆盖会为图像做这个技巧。

                    您要做的第一件事是在情节提要的 Identity Inspector 部分中将 CustomButton 类分配给您的按钮。 然后,您可以在 Attribute Inspector 部分将“alignImageToLeft”切换为 ON 或 OFF(默认为 OFF)。

                    class CustomButton : UIButton {
                    
                        @IBInspectable var alignImageToLeft : Bool = false
                    
                        override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
                            if(alignImageToLeft){
                                let imageRect = super.imageRect(forContentRect: contentRect)
                                let offset = contentRect.minX - imageRect.minX
                                return imageRect.offsetBy(dx: offset, dy: 0.0)
                            }
                            return super.imageRect(forContentRect: contentRect)
                        }
                    }
                    

                    【讨论】:

                      【解决方案17】:

                      一个技巧是:

                      1. 覆盖 titleRectForContentRect 以使按钮的 titleLabelframe 等于按钮的边界
                      2. titleLabeltextAlignment 设置为.Center
                      3. 覆盖imageRectForContentRect 以指定按钮的imageVieworigin.x

                        import UIKit
                        
                        class ButtonWithLeftAlignedImageAndCenteredText: UIButton {
                        
                            override init(frame: CGRect) {
                                super.init(frame: frame)
                        
                                titleLabel?.textAlignment = .Center
                            }
                        
                            override func imageRectForContentRect(contentRect: CGRect) -> CGRect {
                                var imageFrame = super.imageRectForContentRect(contentRect)
                                imageFrame.origin.x = 20 //offset from left edge
                                return imageFrame
                            }
                        
                            override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
                                var titleFrame = super.titleRectForContentRect(contentRect)
                                titleFrame = self.bounds
                                return titleFrame
                            }
                        
                        
                            required init?(coder aDecoder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                            }
                        }
                        

                      【讨论】:

                        【解决方案18】:

                        您可以使用以下代码在 UIButton 上左对齐图像:-

                        第 1 步:

                        //create your UIButton
                        UIButton *post_bNeeds_BTN= [UIButton buttonWithType:UIButtonTypeRoundedRect];
                        post_bNeeds_BTN.frame= CGRectMake(160 ,5 ,150 ,40);
                        [post_bNeeds_BTN addTarget:self action:@selector(post_Buying_Needs_BTN_Pressed:) forControlEvents:UIControlEventTouchUpInside];
                        [post_bNeeds_BTN setBackgroundColor:[UIColor colorWithRed:243/255.0 green:131/255.0 blue:26/255.0 alpha:1.0f]];//230
                        [self.view addSubview:post_bNeeds_BTN];
                        post_bNeeds_BTN.autoresizingMask= UIViewAutoresizingFlexibleWidth;
                        

                        第 2 步:

                        //Add UIImageView on right side the button
                        UIImageView *bNeedsIVw= [[UIImageView alloc] initWithFrame:CGRectMake(5,5,30,30)];
                        bNeedsIVw.image= [UIImage imageNamed:@"postRequir_30.png"];
                        bNeedsIVw.image= [bNeedsIVw.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
                        bNeedsIVw.tintColor= [UIColor whiteColor];
                        [post_bNeeds_BTN addSubview:bNeedsIVw];
                        

                        第 3 步:

                        //also set UILable on UIButton
                        UILabel *bNeedsLbl= [[UILabel alloc] initWithFrame:CGRectMake(40 ,0 ,post_Prod_BTN.frame.size.width-40 ,post_Prod_BTN.frame.size.height)];
                        bNeedsLbl.text= @"Requirements";
                        bNeedsLbl.font= [UIFont systemFontOfSize:16];
                        bNeedsLbl.textColor= [UIColor whiteColor];
                        bNeedsLbl.textAlignment= NSTextAlignmentLeft;
                        [post_bNeeds_BTN addSubview:bNeedsLbl];
                        

                        第 4 步:

                        -(void)post_Buying_Needs_BTN_Pressed:(id)sender{
                            //write your code action here,,
                        }
                        

                        谢谢,

                        【讨论】:

                          【解决方案19】:

                          可以使用扩展程序应用此解决方案。不需要子类化。

                          警告:每次更新文本/图像时都必须调用它。

                          let width = frame.width
                          guard let imageWidth = imageView?.frame.width, let labelWidth = titleLabel?.frame.width else {
                                return
                          }
                          titleEdgeInsets = UIEdgeInsets(top: 0, left: (width - labelWidth)/2.0 - imageWidth, bottom: 0, right: 0)
                          

                          【讨论】:

                            【解决方案20】:

                            此代码使您的按钮图像左对齐,并且标题标签移动到按钮的中心。 b 是按钮 :)

                            b.contentHorizontalAlignment = .Left
                            let left = (b.frameWidth() - b.titleLabel!.frameWidth()) / 2 - CGRectGetMaxX(b.imageView!.frame)
                            b.titleEdgeInsets = UIEdgeInsetsMake(0, left, 0, 0)
                            

                            【讨论】:

                              【解决方案21】:

                              您可能会忘记 UIEdgeInsets,而只是在 UIButton 子类中覆盖 layoutSubviews() 中的框架。

                              要使titleLable居中,只需通过super.bounds.midX和titleLabel.frame.midX之间的差异将水平偏移量添加到titleLabel框架

                                 override func layoutSubviews() {
                                     super.layoutSubviews()
                                     
                                     if let label = titleLabel {
                                         label.frame = label.frame.offsetBy(dx: super.bounds.midX - 
                                              label.frame.midX , dy: 0)
                                     }
                              
                                     // Available space to the left of the titleLabel is simply:
                                     let leftAvailableWidth = label.frame.minX
                              
                                     imageView?.frame = CGRect(x: 0, y: 0, width: <Some width smaller than leftAvailableWidth>, height: super.bound.height)
                                 }
                              

                              【讨论】:

                                【解决方案22】:

                                斯威夫特 5: 您可以通过使用 UIButton 的自定义类来实现这一点。

                                class CustomButton: UIButton {
                                
                                    var imageV = UIImageView()
                                    var titleV = UILabel()
                                
                                    override func awakeFromNib() {
                                
                                        self.imageView?.isHidden = true
                                        self.titleLabel?.isHidden = true
                                
                                        imageV.frame = CGRect(x: 0, y: 0, width: 40, height: self.bounds.height)
                                        imageV.contentMode = .scaleAspectFit
                                
                                        titleV.frame = CGRect(x: 40, y: 0, width: self.bounds.width - 40, height: self.bounds.height)
                                        titleV.font = self.titleLabel?.font
                                        titleV.textAlignment = .center
                                
                                        self.addSubview(imageV)
                                        self.addSubview(titleV)
                                
                                        imageV.image = self.imageView?.image; titleV.text = self.titleLabel?.text
                                
                                        imageV.translatesAutoresizingMaskIntoConstraints = false
                                        imageV.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
                                        imageV.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
                                        imageV.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
                                        imageV.trailingAnchor.constraint(equalTo: titleV.leadingAnchor, constant: 0).isActive = true
                                        imageV.widthAnchor.constraint(equalToConstant: 40).isActive = true
                                
                                        titleV.translatesAutoresizingMaskIntoConstraints = false
                                        titleV.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
                                        titleV.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
                                        titleV.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
                                    }
                                }
                                

                                以后你可以像这样设置图片和文字。

                                button.imageV.image = myImage
                                button.titleV.text = myText
                                

                                结果

                                【讨论】:

                                  【解决方案23】:

                                  Swift 版本:

                                  var button = UIButton()
                                  
                                  newGameButton.setTitle("Новая игра", for: .normal)
                                  newGameButton.setImage(UIImage(named: "energi"), for: .normal)
                                  newGameButton.backgroundColor = .blue
                                  newGameButton.imageEdgeInsets.left = -50
                                  

                                  【讨论】:

                                    【解决方案24】:

                                    这对我来说适用于不同的按钮文本大小。

                                    准确的按钮文本宽度的关键是获取intrinsicContentSize。由于我对按钮宽度使用自动布局,因此我必须从 viewDidAppear 而不是 viewDidLoad 运行此代码,以便已经绘制按钮,因此,按钮框架大小将是准确的。

                                    private func calculateAccountButtonImageViewOffset(button: UIButton, padding: CGFloat = 30.0) -> CGFloat {
                                        let buttonWidth = button.frame.width
                                        let textWidth = button.titleLabel?.intrinsicContentSize.width ?? 0
                                        let imageViewWidth = button.imageView?.frame.size.width ?? 0
                                        let offsetToLeftButtonEdge = buttonWidth - textWidth - imageViewWidth
                                        return offsetToLeftButtonEdge - padding
                                    }
                                    

                                    用法:

                                    let imageViewOffset = calculateAccountButtonImageViewOffset(button: button)
                                    button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 0, bottom: 0.0, right: imageViewOffset)
                                    

                                    按钮标题可以根据需要使用 IB 上的 Title Insets 进行偏移:

                                    【讨论】:

                                      【解决方案25】:

                                      最好创建一个自定义 UIButton 子类以更好地解决此问题。 Apple 可能正在“重置”您的设置。

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2019-10-01
                                        • 2018-07-18
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2017-10-20
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多