How do you set an Attributed Title Color for State in Swift
// create the button
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
button.backgroundColor = UIColor.yellowColor()
// set the attributed title for different states
// .Selected
let mySelectedAttributedTitle = NSAttributedString(string: "Click Here",
attributes: [NSForegroundColorAttributeName : UIColor.greenColor()])
button.setAttributedTitle(mySelectedAttributedTitle, forState: .Selected)
// .Normal
let myNormalAttributedTitle = NSAttributedString(string: "Click Here",
attributes: [NSForegroundColorAttributeName : UIColor.blueColor()])
button.setAttributedTitle(myNormalAttributedTitle, forState: .Normal)
Title color of UIButton won't change on highlighted/selected but background color will
setTitleColor
doesn't have any effect when the title is an attributed string. Either use a plain NSString
or call setAttributedTitle
again after applying the desired color to the attributed string.
UIButton Change Title Color Partially
Use NSMutableAttributedString
for this purpose
private let signUpButton = UIButton().then {
// Creating gray text part
let grayButtonText = NSAttributedString(string: "FirstPart", attributes: [.font: UIFont.systemFont(ofSize: 12), .foregroundColor: UIColor.gray ])
// Creating black text part
let blackButtonText = NSAttributedString(string: "SecondPart", attributes: [.font: UIFont.systemFont(ofSize: 12), .foregroundColor: UIColor.black ])
// Merging two parts together
let buttonTitle = NSMutableAttributedString(attributedString: grayButtonText)
buttonTitle.append(blackButtonText)
// Set it as a title for ".normal" state
$0.setAttributedTitle(buttonTitle, for: .normal)
}
How to set the title text color of UIButton?
You have to use func setTitleColor(_ color: UIColor?, for state: UIControl.State)
the same way you set the actual title text. Docs
isbeauty.setTitleColor(UIColorFromRGB("F21B3F"), for: .normal)
iOS NSAttributedString on UIButton
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:
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,
NSParagraphStyleAttributeName:style}; // Added line
NSDictionary *dict2 = @{NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone),
NSFontAttributeName:font2,
NSParagraphStyleAttributeName:style}; // Added line
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.resolveButton setAttributedTitle:attString forState:UIControlStateNormal];
[[self.resolveButton titleLabel] setNumberOfLines:0];
[[self.resolveButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
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
let style = NSMutableParagraphStyle()
style.alignment = .center
style.lineBreakMode = .byWordWrapping
guard
let font1 = UIFont(name: "HelveticaNeue-Medium", size: 20),
let font2 = UIFont(name: "HelveticaNeue-Light", size: 20) else { return }
let dict1:[String:Any] = [
NSUnderlineStyleAttributeName:NSUnderlineStyle.styleSingle.rawValue,
NSFontAttributeName:font1,
NSParagraphStyleAttributeName:style
]
let dict2:[String:Any] = [
NSUnderlineStyleAttributeName:NSUnderlineStyle.styleNone.rawValue,
NSFontAttributeName:font2,
NSParagraphStyleAttributeName:style
]
let attString = NSMutableAttributedString()
attString.append(NSAttributedString(string: "LINE 1", attributes: dict1))
attString.append(NSAttributedString(string: "line 2", attributes: dict2))
button.setAttributedTitle(attString, for: .normal)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byWordWrapping
iOS button title color won't change
Because your button will turn back to UIControlState.Normal
after you touch it, it become .Highlighted
, then .Normal
You should set sender.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Selected)
to
sender.setTitleColor(UIColor.whiteColor(), forState: UIControlState. Normal)
or, just set it for all the states since u did a check for color like
sender.setTitleColor(UIColor.whiteColor(), forState: [.Normal,.Selected,.Highlighted])
*Edit: Above doesn't work, can use NSAttributedString
instead
if self.loginButton.backgroundColor == UIColor.blackColor() {
let tittle = NSAttributedString(string: "Login", attributes: [NSForegroundColorAttributeName: UIColor.blackColor()])
loginButton.setAttributedTitle(tittle, forState: .Normal)
loginButton.backgroundColor = UIColor.whiteColor()
} else {
let tittle = NSAttributedString(string: "Login", attributes: [NSForegroundColorAttributeName: UIColor.whiteColor()])
loginButton.setAttributedTitle(tittle, forState: .Normal)
loginButton.backgroundColor = UIColor.blackColor()
}
Creating UIButton attributed title based on its original plain text state
Got this to work finally. Turns out that there are several properties of a plain text UIButton that are in several places. Some have helper methods to retrieve directly from the UIButton, some do not.
- Font:
self.titleLabel.font
(no helper method) - Colour:
[self titleColorForState:state]
- Text:
[self titleForState:state]
- Attributed Text:
[self attributedTitleForState]
And a plain text UIButton does not have any text alignment by default, since that's controlled by content horizontal alignment.
As such, I changed up my helper methods (the first is identical, but I had to change the second):
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromExistingAttributedString:(NSAttributedString*)attributedString
{
NSDictionary *attributes = [attributedString attributesAtIndex:0 effectiveRange:NULL];
return [[NSMutableAttributedString alloc] initWithString:title attributes:attributes];
}
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title font:(UIFont*)font color:(UIColor*)color
{
NSMutableAttributedString* mutableTitle = [[NSMutableAttributedString alloc] initWithString:title];
[mutableTitle addAttribute:NSFontAttributeName value:font range:[mutableTitle fullRange]];
[mutableTitle addAttribute:NSForegroundColorAttributeName value:color range:[mutableTitle fullRange]];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[mutableTitle addAttribute:NSParagraphStyleAttributeName value:style range:[mutableTitle fullRange]];
return mutableTitle;
}
And I've implemented it like this:
- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle = [title mutableCopy];
[mutableTitle addAttributes:@{NSKernAttributeName: @(kDefaultKerning)} range:[mutableTitle fullRange]];
[super setAttributedTitle:mutableTitle forState:state];
[self setNeedsDisplay];
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle;
if ([self attributedTitleForState:state]) {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromExistingAttributedString:[self attributedTitleForState:state]];
} else {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title font:self.titleLabel.font color:[self titleColorForState:state]];
}
[self setAttributedTitle:mutableTitle forState:state];
}
Related Topics
How to Get the Realy Fixed Device-Id in Swift
This Class Is Not Key Value Coding-Compliant for the Key Name.'
How to Block Users on Firebase in a Social Media App? for iOS
How to Use Dispatch Groups to Wait to Call Multiple Functions That Depend on Different Data
Convert Float Value to String in Swift
Using Swift to Disable Sleep/Screen Saver for Osx
How to Set Countdowntimer Mode in Datepicker on Swiftui
Load a Collada (Dae) File into Scnnode (Swift - Scenekit)
Mkpointannotations Touch Event in Swift
Datepicker Using Time-Interval in Swiftui
Firebase Sign Out Not Working in Swift
Target Parameter in Dispatchqueue
Swift - 'Bool' Is Not a Subtype of 'Void'
Get Header Data from a Request Response in Swift
Can't Parse JSON Array with JSONdecoder in Swift 4
Why Do I Need to Declare an Optional Value as Nil Explicitly in Struct - Swift