76

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

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

    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);
4

26 回答 26

75

此解决方案适用于 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+。

于 2017-01-10T17:41:09.583 回答
52

最后,我使用 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];

输出看起来像,

带有图像的居中文本

斯威夫特

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)
于 2013-05-06T21:55:55.927 回答
18

对于 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应该是customtype UIButton

这个扩展的leftImageandrightImage也可以UIButtonUIBarButtonItemfor中使用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
    }
}
于 2018-05-02T04:32:54.810 回答
10

我已经尝试了上面几乎所有的解决方案,但都没有像我预期的那样工作(我有两个按钮,每个按钮都有不同的标题和不同的图像宽度)。所以我为 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()

于 2018-03-26T19:25:42.037 回答
9

正如我认为的那样,好的解决方案必须对任何文本都有用,没有硬编码的插入值(这是关于 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 点,所以一些不太长的线条变得太小了,比它必须的要小。

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

于 2013-09-13T10:04:15.000 回答
9
[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];

让我知道它是否不起作用。

我的输出在此处输入图像描述

于 2016-07-08T12:22:01.553 回答
9

我写了一个 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)

瞧!

于 2017-06-09T15:12:32.277 回答
8

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

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];
于 2013-06-29T03:04:16.747 回答
6

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

斯威夫特 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)
    }
}

希望对一些人有所帮助!

于 2019-06-07T10:30:17.213 回答
5

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

子类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)
    }

}
于 2015-09-25T09:39:35.430 回答
3

我用 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)

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

于 2016-05-11T10:38:44.657 回答
2

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

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

3)UITextAlignmentCenter现在是NSTextAlignmentCenter

4)button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

于 2013-01-17T10:22:57.423 回答
2

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

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

于 2015-05-08T22:38:59.787 回答
2

我的SWIFT 5.2解决方案。

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

您要做的第一件事是将 CustomButton 类分配给情节提要的 Identity Inspector 部分中的按钮。然后,您可以在 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)
    }
}
于 2020-04-30T14:13:08.960 回答
2

我知道这个答案有点晚了。但是对于想要使用 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
    }

}
于 2017-05-01T15:50:16.237 回答
2

以下扩展适用于 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)
}
于 2019-01-31T20:22:07.790 回答
1

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

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

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)
于 2018-06-05T19:51:31.247 回答
1

您可能会忘记 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)
   }
于 2020-10-16T08:42:31.940 回答
1

一个技巧是:

  1. 覆盖titleRectForContentRect以使按钮的titleLabel'frame等于按钮的边界
  2. titleLabel's设置textAlignment.Center
  3. 覆盖imageRectForContentRect以指定origin.x按钮的imageView

    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")
        }
    }
    
于 2016-02-15T17:36:19.480 回答
1

您可以使用以下代码在 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,,
}

谢谢,

于 2016-05-02T09:34:10.117 回答
1

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

b.contentHorizontalAlignment = .Left
let left = (b.frameWidth() - b.titleLabel!.frameWidth()) / 2 - CGRectGetMaxX(b.imageView!.frame)
b.titleEdgeInsets = UIEdgeInsetsMake(0, left, 0, 0)
于 2016-10-02T15:24:22.107 回答
0

@trishcode 答案对我有用。我只是将它与 UIButton 的扩展一起使用。

这是代码:

extension UIButton {
func centerImageLeft(padding: CGFloat = 30.0){
    let buttonWidth = self.frame.width
    let textWidth = self.titleLabel?.intrinsicContentSize.width ?? 0
    let imageViewWidth = self.imageView?.frame.size.width ?? 0
    let offsetToLeftButtonEdge = buttonWidth - textWidth - imageViewWidth
    let offset = offsetToLeftButtonEdge - padding
    self.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 0, bottom: 0.0, right: offset)
}
}

然后你可以在 viewDidAppear 方法中这样调用它:

button.centerImageLeft()
于 2022-02-09T14:43:57.327 回答
0

斯威夫特版本:

var button = UIButton()

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

在此处输入图像描述

于 2020-07-20T07:07:44.903 回答
0

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

准确的按钮文本宽度的关键是获取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 进行偏移: 在此处输入图像描述

于 2021-10-21T20:05:22.763 回答
0

Swift 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

结果

在此处输入图像描述

于 2020-01-23T09:03:47.913 回答
-2

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

于 2012-06-08T19:22:02.407 回答