I have a table view (row heights are set to automatic), where each cell has a single UIButton (whose top and bottom is constrained to the cell's contentView.top and contentView.bottom, the leading side is fixed to contentView.leading, and the trailing is dynamically set to <= contentView.trailing, dependent upon the length of text). I need the height of the button to grow depending on the amount of text, so that it can show multi-line text if needed.
Now, I have tried various things which seem like they would do the trick. For example, I followed this SO question, which states to set the following:
myButton.titleLabel?.lineBreakMode = .byWordWrapping
myButton.titleLabel?.numberOfLines = 0
This successfully allows the button's titleLabel to become multi-line, but the button is still not adjusting to fit its title label. See this image for reference.
Note: I set the button's content insets, but these values seem to have no effect when the text becomes multi-line. Clipping still occurs
Based on a few other SO questions, I've come to the conclusion that it has something to do with the UIButton's intrinsicContentSize
, so this SO question recommended subclassing UIButton and then overriding the intrinsicContentSize
property...
class ResizableButton: 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
}
}
...but when I tried this, I got an even wonkier result. It seems to me that I must not be returning the correct value for the intrinsicContentSize
property. If this is the case, does anyone know how I can return the correct value to achieve the result I am looking for? Otherwise, if this is not correct, any other suggestions are welcome. I'm also unsure about my current implementation of the layoutSubviews
method.
Note: I know I could just create a separate UILabel, and handle the multi-line text separately from the UIButton, but I prefer to keep the text within the button itself if this is possible, especially since UIButton's handle selection/deselection animations inherently.
UPDATE: I have tried @valosip's solution. This fixed the content inset issue, but the text is still starting a new line after only a couple letters instead of taking up the full width (See image here). Any solutions for this? Again, note that I have the trailing constraint of the UIButton to be <= contentView.trailing, but UIButton is clearly not getting anywhere near the trailing edge.