224

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

如果我将图像设置为button.image,则内在尺寸似乎再次说明了这一点。

但是,如果我调整titleEdgeInsets按钮的 ,布局不会考虑这一点,而是截断按钮标题。

如何确保按钮的固有宽度占插图?

在此处输入图像描述

编辑:

我正在使用以下内容:

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

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

4

11 回答 11

232

您可以通过结合使用否定和肯定的标题和内容插入,在 Interface Builder 中使其工作(无需编写任何代码)。

在此处输入图像描述

更新:Xcode 7 有一个错误,您不能在 Inset 字段中输入负值Right,但您可以使用它旁边的步进控件来减小该值。(感谢斯图尔特)

这样做会在图像和标题之间增加 8pt 的间距,并将按钮的固有宽度增加相同的量。像这样:

在此处输入图像描述

于 2015-02-02T22:12:17.513 回答
202

您无需重写任何方法或设置任意宽度约束即可解决此问题。您可以在 Interface Builder 中完成所有操作,如下所示。

  • 固有按钮宽度来自标题宽度加上图标宽度加上左右内容边缘插图。

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

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

  • 如果您设置负左图像插入,图像被拉到左侧,但整体按钮宽度不受影响。

  • 如果您设置负左图像插图,则实际布局使用该值的一半。因此,要获得 -20 点左插图,您必须在 Interface Builder 中使用 -40 点左插图值。

因此,您提供了一个足够大的左侧内容插图,以便为所需的左侧插图图标和文本之间的内部填充创建空间,然后通过将您想要的图标和文本之间的填充量加倍来将图标向左移动。结果是一个具有相同左右内容插入的按钮,以及作为一组居中的文本和图标对,它们之间具有特定数量的填充。

一些示例值:

// 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)
于 2016-05-13T20:32:03.357 回答
101

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

- (CGSize) intrinsicContentSize
{
    CGSize s = [super intrinsicContentSize];

    return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right,
                      s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom);
}

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

于 2013-07-23T09:26:41.120 回答
94

您尚未指定如何设置插图,所以我猜您正在使用 titleEdgeInsets ,因为我看到您得到的效果相同。如果我改用 contentEdgeInsets ,它可以正常工作。

- (IBAction)ChangeTitle:(UIButton *)sender {
    self.button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
    [self.button setTitle:@"Long Long Title" forState:UIControlStateNormal];
}
于 2013-07-23T03:06:26.503 回答
25

而对于 Swift 来说,它是这样工作的:

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)
    }
}

爱你斯威夫特

于 2015-03-05T17:53:31.757 回答
18

这个线程有点老了,但我自己也遇到了这个问题,并且能够通过使用负插图来解决它。例如,在这里替换您想要的填充值:

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

结合正确的自动布局约束,您最终会得到一个包含图像和文本的自动调整大小按钮!如下所示,desiredLeftPadding设置为 10。

带有图像和短文本的按钮

带有图像和长文本的按钮

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

于 2013-10-18T02:50:58.570 回答
8

对于Swift 3基于pegpeg的回答:

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)

    }

}
于 2017-08-10T13:24:06.250 回答
7

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

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

在此处输入图像描述

现在要在按钮周围添加边框,只需使用以下方法:

button.contentEdgeInsets = UIEdgeInsetsMake(0,20,0,20);
于 2015-10-21T21:39:25.780 回答
6

我想在我的 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 相互关联的方式需要从每个插图中进行一些取舍。因此,如果您在标题左侧添加一些插图,则必须在右侧添加负插图,并在内容右侧提供更多空间(通过正插图)。

通过添加正确的内容插图以匹配标题插图的移动,我的文本不会超出按钮的范围。

于 2015-05-19T07:36:46.953 回答
3

该选项在界面生成器中也可用。见插图。我将左右设置为 3。就像一个魅力。

界面生成器屏幕截图

于 2014-11-26T15:12:31.563 回答
1

我使用的解决方案是在按钮上添加宽度约束。然后在初始化的某个地方,在设置文本之后,像这样更新宽度约束:

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

无论您的插图是什么,8 都在哪里。

于 2013-10-29T06:00:23.190 回答