UIButton:如何使用imageEdgeInsets和titleEdgeInsets使图像和文本居中? [英] UIButton: how to center an image and a text using imageEdgeInsets and titleEdgeInsets?

查看:92
本文介绍了UIButton:如何使用imageEdgeInsets和titleEdgeInsets使图像和文本居中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我只在一个按钮中放置一个图像并将imageEdgeInsets设置得更接近顶部,则图像保持居中并且所有图像都按预期工作:

If I put only an image in a button and set the imageEdgeInsets more close to the top, the image stays centered and all works as expected:

[button setImage:image forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, 0.0)];

如果我只在一个按钮中放置一个文本并将titleEdgeInsets设置得更接近底部,那么文本将保留居中,一切按预期工作:

If I put only a text in a button and set titleEdgeInsets more close to the bottom, the text stays centered and all works as expected:

[button setTitle:title forState:UIControlStateNormal];
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, -30, 0.0)];

但是,如果我将4行放在一起,文本会干扰图像并且都丢失了中心对齐。

But, if I put the 4 lines together, the text interfere with the image and both lost the center alignment.

我的所有图像的宽度都是30像素,如果我在setTitleEdgeInsets的UIEdgeInsetMake的左参数中放置30,则文本将再次居中。问题是图像永远不会居中,因为它似乎依赖于button.titleLabel大小。我已经尝试了许多按钮大小,图像大小,标题标签大小的计算,并且永远不会完全居中。

All my images has 30 pixels width, and if I put 30 in the left parameter of UIEdgeInsetMake for setTitleEdgeInsets, the text is centered again. The problem is that the image never gets centered because it appears that it is dependent of the button.titleLabel size. I already tried many calculations with button size, image size, titleLabel size and never get both perfectly centered.

有人已经遇到过同样的问题吗?

Someone already had the same problem?

推荐答案

对于它的价值,这里是一个通用的解决方案,将图像定位在文本上方而不使用任何幻数。 请注意,以下代码已过时,您可能应该使用以下某个更新版本

For what it's worth, here's a general solution to positioning the image centered above the text without using any magic numbers. Note that the following code is outdated and you should probably use one of the updated versions below:

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

以下版本包含支持 iOS 7 + 的更改在下面的评论中。我自己没有测试过这段代码,所以我不确定它的效果如何,或者如果在以前版本的iOS下使用它会不会破坏。

The following version contains changes to support iOS 7+ that have been recommended in comments below. I haven't tested this code myself, so I'm not sure how well it works or whether it would break if used under previous versions of iOS.

// the space between the image and text
CGFloat spacing = 6.0;

// lower the text and push it left so it appears centered 
//  below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
  0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);

// raise the image and push it right so it appears centered
//  above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
  - (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);

// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);

Swift

extension UIButton {
  func alignVertical(spacing: CGFloat = 6.0) {
    guard let imageSize = self.imageView?.image?.size,
      let text = self.titleLabel?.text,
      let font = self.titleLabel?.font
      else { return }
    self.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0.0)
    let labelString = NSString(string: text)
    let titleSize = labelString.size(attributes: [NSFontAttributeName: font])
    self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: 0.0, bottom: 0.0, right: -titleSize.width)
    let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
    self.contentEdgeInsets = UIEdgeInsets(top: edgeOffset, left: 0.0, bottom: edgeOffset, right: 0.0)
  }
}

这篇关于UIButton:如何使用imageEdgeInsets和titleEdgeInsets使图像和文本居中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆