Created
July 25, 2014 16:29
-
-
Save brynbodayle/de70eb6a392e90272707 to your computer and use it in GitHub Desktop.
Multiline UIButton + Auto Layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (CGSize)intrinsicContentSize { | |
CGSize boundingSize = CGSizeMake(self.titleLabel.preferredMaxLayoutWidth - self.titleEdgeInsets.left - self.titleEdgeInsets.right, CGFLOAT_MAX); | |
NSAttributedString *attributedTitle = [self attributedTitleForState:self.state]; | |
CGRect boundingRect; | |
if(attributedTitle) { | |
boundingRect = [attributedTitle boundingRectWithSize:boundingSize options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) context:NULL]; | |
} | |
else { | |
NSString *title = [self titleForState:self.state]; | |
boundingRect = [title boundingRectWithSize:boundingSize options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName : self.titleLabel.font} context:NULL]; | |
} | |
return CGSizeMake(boundingRect.size.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right, boundingRect.size.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom); | |
} |
This do not work for me. In result I get this solution:
override func intrinsicContentSize() -> CGSize {
let size = titleLabel?.intrinsicContentSize() ?? CGSizeZero
return CGSizeMake(size.width + titleEdgeInsets.left + titleEdgeInsets.right, size.height + titleEdgeInsets.top + titleEdgeInsets.bottom)
}
@AlexandrGraschenkov solution is works
Works fine, however I found that we need to take contentEdgeInsets into account as well, since some people might have set both.
@AlexandrGraschenkov thanks!
This works for me.
class MultiLineButton: UIButton {
// MARK: - Init
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
self.titleLabel?.numberOfLines = 0
self.titleLabel?.lineBreakMode = .byWordWrapping
}
// MARK: - Overrides
override var intrinsicContentSize: CGSize {
titleLabel?.intrinsicContentSize ?? .zero
}
override func layoutSubviews() {
super.layoutSubviews()
titleLabel?.preferredMaxLayoutWidth = titleLabel?.frame.size.width ?? 0
super.layoutSubviews()
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's a little code snippet for a UIButton subclass which allows you to use a multi line UIButton with Auto Layout. This also solves the issue UIButton can have with Auto Layout where it doesn't allot for the titleEdgeInsets.
Just make sure you are setting the preferredMaxLayoutWidth for your label so it will wrap correctly. Here's a great post describing how to do that.
http://devetc.org/code/2014/07/07/auto-layout-and-views-that-wrap.html
Unfortunately this only seems to be working in iOS 8 right now.