我想在两行文本的左边放置一个图标,这样在图像和文本开始之间有大约2-3像素的空间。控件本身水平居中对齐(通过接口生成器设置)
这个按钮应该是这样的:
| |
|[Image] Add To |
| Favorites |
我试图配置这与contenttedgeinset, imageEdgeInsets和titleEdgeInsets无效。我知道,负值会使边缘扩大,而正值会使边缘缩小,使边缘更接近中心。
我试着:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];
但这并没有正确显示它。我一直在调整这些值,但从-5到-10的左插入值似乎不会以预期的方式移动它。-10将文本一直向左移动,所以我期望-5将它从左侧移动一半,但事实并非如此。
嵌套背后的逻辑是什么?我不熟悉图像放置和相关术语。
我用这个SO问题作为参考,但我的价值观有些不对。
UIButton:如何使用imageEdgeInsets和titleEdgeInsets居中图像和文本?
我同意imageEdgeInsets和titleEdgeInsets的文档应该更好,但我想出了如何获得正确的定位而不求助于试验和错误。
这个问题的大意是,如果你想同时以文本和图像为中心。我们不希望图像和文本分别居中,我们希望图像和文本作为一个单独的实体放在一起。这实际上是UIButton已经做的,所以我们只需要调整间距。
CGFloat spacing = 10; // the amount of spacing to appear between image and title
tabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
我还把它变成了UIButton的一个类别,这样它就很容易使用:
UIButton + h位置。
@interface UIButton(ImageTitleCentering)
-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing;
@end
公元UIButton +位置。
@implementation UIButton(ImageTitleCentering)
-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing {
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);
self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
}
@end
所以现在我要做的就是
[button centerButtonAndImageWithSpacing:10];
我每次都能得到我想要的。没有更多的混乱与边缘插入手动。
编辑:交换图像和文本
回复@Javal的评论
使用相同的机制,我们可以交换图像和文本。要完成交换,只需使用负间距,但也包括文本和图像的宽度。这将要求帧是已知的和布局已经执行。
[self.view layoutIfNeeded];
CGFloat flippedSpacing = -(desiredSpacing + button.currentImage.size.width + button.titleLabel.frame.size.width);
[button centerButtonAndImageWithSpacing:flippedSpacing];
当然,你可能会想要为此创建一个很好的方法,可能会添加第二个类别方法,这是留给读者的练习。
如果你想做一些类似的东西
你需要
1.为按钮设置水平和垂直对齐
Find all required values and set UIImageEdgeInsets
CGSize buttonSize = button.frame.size;
NSString *buttonTitle = button.titleLabel.text;
CGSize titleSize = [buttonTitle sizeWithAttributes:@{ NSFontAttributeName : [UIFont camFontZonaProBoldWithSize:12.f] }];
UIImage *buttonImage = button.imageView.image;
CGSize buttonImageSize = buttonImage.size;
CGFloat offsetBetweenImageAndText = 10; //vertical space between image and text
[button setImageEdgeInsets:UIEdgeInsetsMake((buttonSize.height - (titleSize.height + buttonImageSize.height)) / 2 - offsetBetweenImageAndText,
(buttonSize.width - buttonImageSize.width) / 2,
0,0)];
[button setTitleEdgeInsets:UIEdgeInsetsMake((buttonSize.height - (titleSize.height + buttonImageSize.height)) / 2 + buttonImageSize.height + offsetBetweenImageAndText,
titleSize.width + [button imageEdgeInsets].left > buttonSize.width ? -buttonImage.size.width + (buttonSize.width - titleSize.width) / 2 : (buttonSize.width - titleSize.width) / 2 - buttonImage.size.width,
0,0)];
这将在按钮上排列标题和图像。
此外,请注意更新这在每个转播
斯威夫特
import UIKit
extension UIButton {
// MARK: - UIButton+Aligment
func alignContentVerticallyByCenter(offset:CGFloat = 10) {
let buttonSize = frame.size
if let titleLabel = titleLabel,
let imageView = imageView {
if let buttonTitle = titleLabel.text,
let image = imageView.image {
let titleString:NSString = NSString(string: buttonTitle)
let titleSize = titleString.sizeWithAttributes([
NSFontAttributeName : titleLabel.font
])
let buttonImageSize = image.size
let topImageOffset = (buttonSize.height - (titleSize.height + buttonImageSize.height + offset)) / 2
let leftImageOffset = (buttonSize.width - buttonImageSize.width) / 2
imageEdgeInsets = UIEdgeInsetsMake(topImageOffset,
leftImageOffset,
0,0)
let titleTopOffset = topImageOffset + offset + buttonImageSize.height
let leftTitleOffset = (buttonSize.width - titleSize.width) / 2 - image.size.width
titleEdgeInsets = UIEdgeInsetsMake(titleTopOffset,
leftTitleOffset,
0,0)
}
}
}
}
我的垂直定心方法:
extension UIButton {
/// Layout image and title with vertical centering.
/// - Parameters:
/// - size: The button size.
/// - imageTopOffset: Top offset for image.
/// - spacing: Distance between image and title.
func verticalAlignmentByCenter(size: CGSize, imageTopOffset: CGFloat, spacing: CGFloat) {
let contentRect = contentRect(forBounds: CGRect(origin: .zero, size: size))
let imageRect = imageRect(forContentRect: contentRect)
let titleRect = titleRect(forContentRect: contentRect)
let imageTop = imageTopOffset - imageRect.origin.y
let imageLeft = contentRect.width/2 - imageRect.width/2
imageEdgeInsets = UIEdgeInsets(top: imageTop, left: imageLeft, bottom: 0, right: 0)
let titleTop = imageTopOffset + spacing + imageRect.height - titleRect.origin.y
let titleLeft = titleRect.origin.x - contentRect.width/2 - titleRect.width/2
titleEdgeInsets = UIEdgeInsets(top: titleTop, left: titleLeft, bottom: 0, right: 0)
}
}
@ravron非常出色地给出了这个答案。
在我的例子中,我不仅需要在图像和标题之间添加水平宽度,还需要在按钮的“开头”和“结尾”添加水平空间。
因此,我使用了内部图像和标签的intrinsicContentSize:
接收视图的自然大小,只考虑视图本身的属性。
| |
|[LEADING SPACE] [Image] [SPACE BETWEEN IMAGE AND TITLE] Add To [TRAILING SPACE]|
| Favorites |
let leadingTrailingSpace = 10
let horizontalWidthBetweenImageAndTitle = 4
let insetAmount = horizontalWidthBetweenImageAndTitle / CGFloat(2)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -CGFloat(insetAmount), bottom: 0, right: insetAmount);
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: CGFloat(insetAmount), bottom: 0, right: -insetAmount);
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: CGFloat(insetAmount), bottom: 0, right: insetAmount);
let buttonWidth =
(button.titleLabel?.intrinsicContentSize.width ?? 0) +
(button.imageView?.intrinsicContentSize.width ?? 0)
+ insetAmount
+ leadingTrailingSpace
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true