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.
Swift 4.x version of Kubba's answer:
Need to Update Line Break as Clip/WordWrap/ in Interface builder to corresponding buttons.
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 } }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With