I'm using iOS 6, so attributed strings should be easy to use, right? Well... not so much.
What I want to do:
Using a custom subclass of UIButton
(it doesn't do anything custom to titleLabel
), I'd like to have a multi-line, attributed title that is:
- All caps (I realize that's not part of the attributes) on the first line
- Bolded on the first line
- Underlined on the first line
- "Normal" weight on the second line
- Non-underlined on the second line
- Centered on both lines
I've been able to get #'s 1 through 5 so far (at least, I thought I did, but current testing is yielding errors with multi-line text), but when I tried to do something (anything!) to get the text to be centered, my app keeps crashing. When I try to get all 6 items working (through various methods), I get the following crash/error:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason:
'NSAttributedString invalid for autoresizing,
it must have a single spanning paragraph style
(or none) with a non-wrapping lineBreakMode.'
Based on what I've tried, it appears that I can have one of the following options, but not both:
- A multi-line, centered label
- An attributed label
I can live with one or the other if I must, but I can't believe that I can't have what seems to be a fairly straightforward concept.
Can someone please tell me what I've got wrong?
Here's the last iteration of the code I'm trying:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];
UIFont *font1 = [UIFont fontWithName:@"HelveticaNeue-Medium" size:20.0f];
UIFont *font2 = [UIFont fontWithName:@"HelveticaNeue-Light" size:20.0f];
NSDictionary *dict1 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),
NSFontAttributeName:font1};
NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone),
NSFontAttributeName:font2};
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"LINE 1\n" attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:@"line 2" attributes:dict2]];
[[self buttonToStyle] setAttributedTitle:attString forState:UIControlStateNormal];
[[[self buttonToStyle] titleLabel] setNumberOfLines:0];
[[[self buttonToStyle] titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
Two line
UIButton
withNSAttributedString
title inSwift 5.1
:It looks to me like you forgot in your code to use the "style" object that you set up.. you just instantiated it. You should modify your code to look like this:
Note that I only added the lines that define the NSParagraphStyleAttributeName.. everything else is the same.. and this is what I get for the button:
And here it is in Swift 3.0
With Swift 5.1 and iOS 13.1, you can use the
UIButton
subclass implementation below in order to solve your problem:Usage:
As an alternative if you really need a button of type
system
, you may use the following code:Usage:
The two screen shots below show the result display for the
UIButton
subclass (on the left) and for thesystem
type button (on the right):