我来这个派对有点晚,但我想我有一些有用的东西要补充。
Kekoa的答案很好,但正如RonLugge所提到的,它会使按钮不再尊重sizeToFit,更重要的是,它会导致按钮在固有大小时剪辑其内容。呵!
不过,首先
简单解释一下我是如何相信imageEdgeInsets和titleEdgeInsets工作的:
imageEdgeInsets的文档有以下内容:
使用此属性可调整按钮图像的有效绘图矩形的大小和位置。您可以为这四个嵌入(顶部、左侧、底部、右侧)中的每一个指定不同的值。正值会缩小或插入这条边——使它更靠近按钮的中心。负值会使这条边扩大或开始。
我相信这个文档是在想象这个按钮没有标题,只有一个图像的情况下编写的。用这种方式思考更有意义,并且表现得像UIEdgeInsets通常做的那样。基本上,图像的帧(或标题,带有titleEdgeInsets)对于正插入向内移动,对于负插入向外移动。
好吧,那又怎样?
我快到了!这是你默认设置的,设置一个图像和一个标题(按钮边框是绿色的,只是为了显示它的位置):
当你想要图像和标题之间有空格,而又不造成两者被压缩时,你需要设置四个不同的insets,图像和标题各两个。这是因为你不想改变这些元素帧的大小,而只是改变它们的位置。当你开始以这种方式思考时,Kekoa的优秀类别所需要的改变就变得清晰起来:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}
@end
但是等等,你说,当我这样做的时候,我得到了这个:
噢,是的!我忘了,医生警告过我。他们部分地说:
此属性仅用于布局期间定位图像。按钮不使用此属性来确定intrinsicContentSize和sizeThatFits:。
但有一个属性可以提供帮助,那就是contenttedgeinsets。这方面的医生说:
按钮使用这个属性来确定intrinsicContentSize和sizeThatFits:。
听起来不错。所以让我们再一次调整这个类别:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}
@end
得到什么?
在我看来是赢家。
在Swift中工作,却不想做任何思考?下面是Swift扩展的最终版本:
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
let isRTL = UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
if isRTL {
imageEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: -insetAmount)
} else {
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}
}