UIButton that resizes to fit its titleLabel

autolayout, ios, uibutton, uilabel

Solution

I've gotten this to work, but you have to use a custom button, not a system type. Give the button both width and height constraints, and make an IBOutlet to the height constraint (heightCon in my code) so you can adjust it in code.

- (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;
}

After Edit:

I found that you can also do this more simply, and with a system button if you make a subclass, and use this code,

@implementation RDButton

-(CGSize)intrinsicContentSize {
    return CGSizeMake(self.frame.size.width, self.titleLabel.frame.size.height);
}

The overridden intrinsicContentSize method is called when you set the title. You shouldn't set a height constraint in this case.

Problem

I have a `UIButton` that I add to my view controller's view in a storyboard. I add centering constraints to position it and leading space constraints to limit its width. In code I add: ``` 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]; ``` The result is shown below: I want the button to size to its content. How can I do this? I've tried ``` [self.button sizeToFit]; ``` and I've tried setting the content hugging and compression resistance autolayout constraints priorities to required. I've also tried explicitly setting the `contentEdgeInsets` and `titleEdgeInsets` to `UIEdgeInsetsZero` and calling `invalidateIntrinsicContentSize`. I've also noticed that if I place newline characters in the title string, the button does seem to resize to fit its content. I'm running on Xcode 6 and iOS 8 on the iPhone 6 Simulator.

Original source