左alignment图像和UIButton上的中心文本

我看过有关右alignment的post,但是我不能左alignment工作。 我想要button占据屏幕的宽度,左边的图像和标题/文本在中心。

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

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

在我的最后,我使用UIEdgeInsetsMake做了这个,左边的angular落计算到中心。 我不确定是否有什么东西可以使文本在中心alignment,但是这对我很有用。 确保通过计算宽度将左侧angular落设置到所需的位置。 例如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]; 

输出看起来像,

图片160wpb4.png

这个解决scheme与Swift 3一起使用,并且尊重原始内容和图像边缘插入,同时保持标题标签总是居中在可用空间中,这使得更容易调整边距:

 @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) } } 

以下插入:

在这里输入图像说明

会导致这样的结果:

在这里输入图像说明


额外:正确alignment

这段代码会做同样的事情,但是将图标alignment到右边:

 @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) } } 

在这里输入图像说明

此解决scheme使用semanticContentAttribute因此它需要iOS 9+。


EXTRA:使用titleRect而不是insets的结果相同

此解决scheme获得相同的结果,但不是使用UIButton insets重新定位标题框架,而是重写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) } } 

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

 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的string之后,我还添加了一些像这样的string:

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

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

 [buttonView.titleLabel setAdjustsFontSizeToFitWidth:YES]; 

作品效果不是很好,看起来像是一步缩小了3-4个点的字体大小,所以有些不太长的线条变得太小了。

这段代码允许我们将任何文本放在button标题空间的正中间。

创build你的button,并设置文本alignment为中心,然后添加:

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

这适用于我,为几个button,不同的图像宽度和不同的标题长度:

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

让我知道,如果它不工作。

我的输出 在这里输入图像说明

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

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

3) UITextAlignmentCenter现在是NSTextAlignmentCenter

4) button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

我在这里看到很多解决scheme,重点放在左侧的图标上。 我认为只需添加一个UIImageView,将button的左侧和图像alignment,并将它们居中在一起,这样会更容易。 然后,你可以玩一点偏移,使其看起来不错。

没有代码,全部在Interface Builder中。

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

瞧!

最好是创build一个自定义的UIButton子类,以更好的方式解决这个问题。 苹果可能会“重置”您的设置。

一招是:

  1. 重写titleRectForContentRect ,使button的titleLabelframe等于button的边界
  2. titleLabeltextAlignment.Center
  3. 重写imageRectForContentRect来指定button的origin.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") } } 

您可以使用下面的代码来左alignmentUIButton上的图像: –

步骤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,, } 

谢谢,

我在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) } } 

我想我的任何方式我的button文字的样式,保持中心alignment。 然后我会在我的button上调用这个方法 –

 myButton.setLeftImage("image_name", 30.0) 

这将导致我的图像与左边界的一些填充左alignment。

此代码使您的button图像左alignment,标题标签移动到button的中心。 b是button:)

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

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

 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 } }