UIButton调整大小以适应其titleLabel

Dar*_*ren 34 uibutton uilabel ios autolayout

我有一个UIButton我在故事板中添加到我的视图控制器的视图.我添加居中约束来定位它并引导空间约束以限制其宽度.在代码中我添加:

self.button.titleLabel.numberOfLines = 0;
self.button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.button setTitle:@"A real real real real real real real real long long name." forState:UIControlStateNormal];
self.button.backgroundColor = [UIColor redColor];
self.button.titleLabel.backgroundColor = [UIColor blueColor];
Run Code Online (Sandbox Code Playgroud)

结果如下所示:

在此输入图像描述

我希望按钮的大小适合其内容.我怎样才能做到这一点?

我试过了

[self.button sizeToFit];
Run Code Online (Sandbox Code Playgroud)

我已经尝试将内容拥抱和压缩阻力自动布局约束优先级设置为所需.

我也试过明确设置contentEdgeInsetstitleEdgeInsetsto UIEdgeInsetsZero和调用invalidateIntrinsicContentSize.

我还注意到,如果我在标题字符串中放置换行符,那么按钮似乎会调整大小以适应其内容.

我在iPhone 6模拟器上运行Xcode 6和iOS 8.

A. *_*sha 27

Swift 4.xKubba的答案:

需要将Line Break作为Clip/WordWrap / in Interface构建器更新为相应的按钮.

class ResizableButton: UIButton {
    override var intrinsicContentSize: CGSize {
       let labelSize = titleLabel?.sizeThatFits(CGSize(width: frame.width, height: .greatestFiniteMagnitude)) ?? .zero
       let desiredButtonSize = CGSize(width: labelSize.width + titleEdgeInsets.left + titleEdgeInsets.right, height: labelSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom)

       return desiredButtonSize
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对我不起作用:titleLabel 仍然超出 UIButton 的框架。 (2认同)

rde*_*mar 20

我已经开始工作,但你必须使用自定义按钮,而不是系统类型.给按钮提供宽度和高度约束,并将IBOutlet设置为高度约束(我的代码中的heightCon),以便您可以在代码中调整它.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.button.titleLabel.numberOfLines = 0;
    self.button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [self.button setTitle:@"A real real real real real real real real long long name." forState:UIControlStateNormal];
    [self.button addTarget:self action:@selector(doStuff:) forControlEvents:UIControlEventTouchUpInside];
    self.button.backgroundColor = [UIColor redColor];
    self.button.titleLabel.backgroundColor = [UIColor blueColor];
    [self.button layoutIfNeeded]; // need this to update the button's titleLabel's size
    self.heightCon.constant = self.button.titleLabel.frame.size.height;
}
Run Code Online (Sandbox Code Playgroud)

编辑后:

我发现你也可以更简单地做到这一点,并且如果你创建一个子类,使用系统按钮,并使用这个代码,

@implementation RDButton

-(CGSize)intrinsicContentSize {
    return CGSizeMake(self.frame.size.width, self.titleLabel.frame.size.height);
}
Run Code Online (Sandbox Code Playgroud)

设置标题时会调用重写的intrinsicContentSize方法.在这种情况下,您不应该设置高度约束.


Kub*_*bba 16

有同样的问题.这种事只有在UIButtontitleLabel具有多行.这是UIKit中的一个错误吗?

我的Swift解决方案:

class ResizableButton: UIButton {    
    override var intrinsicContentSize: CGSize {
        let labelSize = titleLabel?.sizeThatFits(CGSize(width: frame.size.width, height: CGFloat.greatestFiniteMagnitude)) ?? .zero
        let desiredButtonSize = CGSize(width: labelSize.width + titleEdgeInsets.left + titleEdgeInsets.right, height: labelSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom)

        return desiredButtonSize
    }
}
Run Code Online (Sandbox Code Playgroud)


Lor*_*esh 7

我为此苦苦挣扎了一段时间,最终通过继承 UIButton 并添加这两个函数使其工作

class GoalsButton: UIButton {

    override var intrinsicContentSize: CGSize {
        return self.titleLabel!.intrinsicContentSize
    }

    // Whever the button is changed or needs to layout subviews,
    override func layoutSubviews() {
        super.layoutSubviews()
        titleLabel?.preferredMaxLayoutWidth = self.titleLabel!.frame.size.width
    }
}
Run Code Online (Sandbox Code Playgroud)