UIButton:如何使用imageEdgeInsets和titleEdgeInsets将图像和文本居中?
如果我只在按钮中放置图像,并将imageEdgeInsets设置得更靠近顶部,则图像保持居中状态,并且按预期工作:
[button setImage:image forState:UIControlStateNormal];
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, 0.0)];
如果我只在按钮中放置一个文本,并将titleEdgeInsets设置得更靠近底部,则文本保持居中,并且所有工作都按预期工作:
[button setTitle:title forState:UIControlStateNormal];
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, -30, 0.0)];
但是,如果我将4条线放在一起,则文字会干扰图像,并且都会丢失中心对齐。
我所有的图像都有30像素的宽度,如果我在UIEdgeInsetMake的左边参数中为setTitleEdgeInsets放置了30,则文本再次居中。 问题是图像永远不会居中,因为它看起来取决于button.titleLabel大小。 我已经尝试了许多按钮大小,图像大小,titleLabel大小的计算,并且永远都不会完全居中。
有人已经有同样的问题?
对于它的价值,这里有一个通用的解决方案,将图像定位在文本上方而不使用任何幻数。 请注意,以下代码已过时,您应该使用以下更新版本之一 :
// 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 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)
}
}
发现如何。
首先,配置titleLabel
的文本(因为样式,即粗体,斜体等)。 然后,使用setTitleEdgeInsets
考虑图像的宽度:
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitle:title forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont boldSystemFontOfSize:10.0]];
// Left inset is the negative of image width.
[button setTitleEdgeInsets:UIEdgeInsetsMake(0.0, -image.size.width, -25.0, 0.0)];
之后,使用setTitleEdgeInsets
考虑文本边界的宽度:
[button setImage:image forState:UIControlStateNormal];
// Right inset is the negative of text bounds width.
[button setImageEdgeInsets:UIEdgeInsetsMake(-15.0, 0.0, 0.0, -button.titleLabel.bounds.size.width)];
现在图像和文字将居中(在这个例子中,图像出现在文字上方)。
干杯。
你可以用这个Swift扩展来完成,部分基于Jesse Crossen的回答:
extension UIButton {
func centerLabelVerticallyWithPadding(spacing:CGFloat) {
// update positioning of image and title
let imageSize = self.imageView.frame.size
self.titleEdgeInsets = UIEdgeInsets(top:0,
left:-imageSize.width,
bottom:-(imageSize.height + spacing),
right:0)
let titleSize = self.titleLabel.frame.size
self.imageEdgeInsets = UIEdgeInsets(top:-(titleSize.height + spacing),
left:0,
bottom: 0,
right:-titleSize.width)
// reset contentInset, so intrinsicContentSize() is still accurate
let trueContentSize = CGRectUnion(self.titleLabel.frame, self.imageView.frame).size
let oldContentSize = self.intrinsicContentSize()
let heightDelta = trueContentSize.height - oldContentSize.height
let widthDelta = trueContentSize.width - oldContentSize.width
self.contentEdgeInsets = UIEdgeInsets(top:heightDelta/2.0,
left:widthDelta/2.0,
bottom:heightDelta/2.0,
right:widthDelta/2.0)
}
}
这定义了一个函数centerLabelVerticallyWithPadding
,适当地设置标题和图像插入。
它还设置了contentEdgeInsets,我认为这对于确保intrinsicContentSize
仍然正常工作是必需的,这将需要使用自动布局。
我相信UIButton的所有解决方案在技术上都是非法的,因为你不应该继承UIKit控件。 也就是说,理论上他们可能会在未来的版本中打破。
链接地址: http://www.djcxy.com/p/28243.html上一篇: UIButton: how to center an image and a text using imageEdgeInsets and titleEdgeInsets?