Autolayout – UIButton的内在大小不包括标题插入

如果我有一个UIButton使用自动布局排列,其大小调整很好,以适应其内容。

如果我设置一个图像为button.image ,内在大小似乎再次考虑到这一点。

但是,如果我调整button的titleEdgeInsets ,布局不会考虑这个,而是截断button标题。

我怎样才能确保button的内在宽度占内嵌?

在这里输入图像说明

编辑:

我正在使用以下内容:

 [self.backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)]; 

目标是在图像和文本之间添加一些分隔。

你可以解决这个问题,而不必重写任何方法或设置任意宽度约束。 您可以在界面生成器中完成以下操作。

  • 内在button宽度是从标题宽度加上图标宽度加上左侧和右侧内容边的插入导出的。

  • 如果一个button同时具有图像和文本,则它们作为一个组居中居中,两者之间没有填充。

  • 如果添加一个左侧内容插图,它是相对于文本计算的,而不是文本+图标。

  • 如果您设置了一个负的左侧图像插图,图像被拉出到左侧,但整体button宽度不受影响。

  • 如果您设置负值左侧图像插图,实际布局使用该值的一半。 所以要得到一个-20的左边插入,你必须在Interface Builder中使用一个-40点左边的插入值。

因此,您可以提供足够大的左侧内容插图,以便为图标和文本之间的所需左侧内插内侧填充创build空间,然后将图标与文本之间的所需填充量加倍,从而向左移动图标。 结果是具有相等的左右内容插入的button以及以一组为中心的文本和图标对,在它们之间具有特定的填充量。

一些示例值:

 // Produces a button with the layout: // |-20-icon-10-text-20-| // AutoLayout intrinsic width works as you'd desire. button.contentEdgeInsets = UIEdgeInsetsMake(10, 30, 10, 20) button.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0) 

您可以通过使用负面和正面标题和内容插页的组合来使其在Interface Builder中工作(无需编写任何代码)。

在这里输入图像说明

更新 :Xcode 7有一个错误,你不能在Right插入字段中input负值,但你可以使用它旁边的步进控制来减less值。 (谢谢Stuart)

这样做将在图像和标题之间添加8pt的间距,并且将按相同的数量增加button的固有宽度。 喜欢这个:

在这里输入图像说明

为什么不重写UIView上的intrinsicContentSize方法? 例如:

 - (CGSize) intrinsicContentSize { CGSize s = [super intrinsicContentSize]; return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right, s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom); } 

这应该告诉自动布局系统,它应该增加button的大小以允许插入和显示全文。 我不在自己的电脑上,所以我没有testing过。

你还没有指定你如何设置插入,所以我猜你正在使用titleEdgeInsets,因为我看到了相同的效果。 如果我使用contentEdgeInsets,它可以正常工作。

 - (IBAction)ChangeTitle:(UIButton *)sender { self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20); [self.button setTitle:@"Long Long Title" forState:UIControlStateNormal]; } 

这个线程有点老了,但我自己碰到了这个,并能够通过使用负插入来解决这个问题。 例如,在这里replace你想要的填充值:

 UIButton* myButton = [[UIButton alloc] init]; // setup some autolayout constraints here myButton.titleEdgeInsets = UIEdgeInsetsMake(-desiredBottomPadding, -desiredRightPadding, -desiredTopPadding, -desiredLeftPadding); 

结合正确的自动布局约束,您将得到一个包含图像和文本的自动resize的button! 以下将desiredLeftPadding设置为10。

button与图像和短文本

带有图像和长文本的button

您可以看到button的实际框架不包含标签(因为标签向右移动了10个点,在边界之外),但是在文本和图片之间填充了10个点。

而Swift的工作是这样的:

 extension UIButton { public override func intrinsicContentSize() -> CGSize { let intrinsicContentSize = super.intrinsicContentSize() let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom return CGSize(width: adjustedWidth, height: adjustedHeight) } } 

爱你Swift

以上所有不适用于iOS 9+ ,我所做的是:

  • 添加一个宽度约束(当button没有任何文本时为最小宽度,如果提供了文本,button将自动缩放)
  • 将关系设置为大于或等于

在这里输入图像说明

现在要在button周围添加一个边框,只需使用以下方法:

 button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20); 

该选项也可在界面构build器中使用。 见插图。 我左右设置3.像一个魅力工程。

界面生成器截图

我想在我的UIButton图标和标签之间添加一个5pt的空格。 我是这样实现的:

 UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom]; // more button config etc infoButton.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 5); infoButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, -5); 

contentEdgeInsets,titleEdgeInsets和imageEdgeInsets彼此相关的方式需要从每个插入一点一点。 所以,如果你在标题的左边添加一些插图,你必须在右边添加负插入,并在内容上提供更多的空间(通过正插图)。

通过添加一个正确的内容插入来匹配标题插入的移位,我的文本不会超出button的范围。

对于基于Pegpeg的答案Swift 3

 extension UIButton { override open var intrinsicContentSize: CGSize { let intrinsicContentSize = super.intrinsicContentSize let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom return CGSize(width: adjustedWidth, height: adjustedHeight) } } 

我使用的解决scheme是在button上添加宽度约束。 然后在初始化的某个地方,你的文本被设置后,更新宽度约束如下所示:

self.buttonWidthConstraint.constant = self.shareButton.intrinsicContentSize.width + 8;

无论你在哪里,无论哪里都是8。