UIButton custom attributed font NSRange iOS - ios

Im trying to make a custom font using attributed string for custom UIButton in xcode using swift 2.0
However it works fine in interface builder but not working in any device or simulator, I'm using xcode 7.3 latest with ios 9.3 but unfortunately it seems a bug in xcode/ios. After searching it from google, I came to realize that its should be treat programatically with swift.
My goal is to just put custom font with NSRange such that I have attributed string of ABCDEF with new line after each alphabet. And I just need to setup the Custom font for first two elements via swift. Below is the example
A <--- font1
B <--- fontMiddle
CDEF <--- font1
P.S: I need exact font size and color which is set in interface builder and just want to set the custom readable font for swift
Here's my try:
let size = (tryButton?.titleLabel?.font?.pointSize)!
let labelFont = UIFont(name: "font1", size: size)
let middleFont = UIFont(name: "fontMiddle", size: size)
let attributedString = NSMutableAttributedString(string:(tryButton.titleLabel?.text)!)
attributedString.addAttribute(NSFontAttributeName, value: labelFont!, range: NSRange(location: 0, length: 1) )
attributedString.addAttribute(NSFontAttributeName, value: middleFont!, range: NSRange(location: 1, length: 2) )
attributedString.addAttribute(NSFontAttributeName, value: labelFont!, range: NSRange(location: 2, length: attributedString.lenght) )
tryButton.setAttributedTitle(attributedString, forState: .Normal)

Related

Why is underline style not working for a NSAttributedString? [duplicate]

This question already has an answer here:
How to use NSUnderlineStyle.PatternDot
(1 answer)
Closed 1 year ago.
I have the following code to try to underline a label's string.
let attributedString = NSMutableAttributedString(string: "Hello World!")
attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single, range: NSRange.init(location: 0, length: attributedString.length))
label.attributedText = attributedString
However, when running the code the label shows Hello World! with no underline.
I'm running Xcode 12.4, and using an iOS 14.4 iPhone 12 Pro Max simulator.
It seems like this is a bug. Changing the value from NSUnderlineStyle.single to 1 fixes the issue.
The final code would look something like the following.
let attributedString = NSMutableAttributedString(string: "Hello World!")
attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: NSRange.init(location: 0, length: attributedString.length))
label.attributedText = attributedString

Why does changing the text of a UILabel not reset text attributes on iOS 13?

On iOS 12, if one changes the text of a UILabel it resets the text attributes. On iOS 13 however, text attributes such as color, typeface, letter spacing, et cetera are kept when the text is changed. What has changed?
An example:
label.text = "Hello world"
let attributedString = NSMutableAttributedString(string: label.text ?? " ")
attributedString.addAttributes([.foregroundColor: UIColor.red], range: NSRange(location: 0, length: attributedString.length))
label.attributedText = attributedString
label.text = "What's up world" // Text is red on iOS 13, default black on iOS 12.
Seems like from iOS 13, if you set and attribute to the entire text, it will persist! If you don't apply the attribute on the entire range of the text, it behaves like before.
You have some options to get around it:
Not applying it on the entire range (Happens most of the times):
attributedString.addAttributes([
.foregroundColor: UIColor.red,
.backgroundColor: UIColor.green
], range: NSRange(location: 0, length: 3))
Perform a version check (Maybe with a little extension)
#available(iOS 13.0, *)
extension UILabel {
func setTextWithoutAttributes(_ text: String) {
// Get rid of the holding attributes instance as Asperi mentioned or in another way you like
self.attributedText = nil
// Set the text
self.text = text
}
}
You did not reset attributedText, but documentation says - if set, the label ignores the properties above (see below for UILabel.h interface, in obj-c it is more correctly visible):
#property(null_resettable, nonatomic,strong) UIColor *textColor UI_APPEARANCE_SELECTOR; // default is labelColor
...
// the underlying attributed string drawn by the label, if set, the label ignores the properties above.
#property(nullable, nonatomic,copy) NSAttributedString *attributedText API_AVAILABLE(ios(6.0)); // default is nil
so behaves as specified (before it might be a bug, that now is fixed)
The solution of your case should be
label.attributedText = attributedString
...
label.attributedText = nil // << reset to default !!
label.text = "What's up world"

Why my label is truncating even though the number of lines is 0 and no height constraint?

I have a label and I added a attributed string to it. The string is,
let nameText = "My name is Shreesha and Im an iOS developer. My name is Shreesha and Im an iOS developer."`My name is Shreesha and Im an iOS developer. My name is Shreesha and Im an iOS developer.`
In this text I'm trying to add a * in the beginning of the text so I used an attributed string and the code looks like this,
func attributedTextForFeeApplies() -> NSAttributedString {
let attributedText = NSMutableAttributedString(string: "* " + nameText)
attributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue, range: NSMakeRange(0, attributedText.length))
attributedText.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize: 10), range: NSMakeRange(0, attributedText.length))
let superScriptString = "* "
attributedText.addAttribute(NSAttributedStringKey.baselineOffset, value: 2, range: NSMakeRange(0, superScriptString.characters.count))
attributedText.addAttribute(NSAttributedStringKey.font, value: UIFont.systemFont(ofSize: 9), range: NSMakeRange(0, superScriptString.characters.count))
attributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue, range: NSMakeRange(0, superScriptString.characters.count))
let superscriptAttributedString = attributedText
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = .byTruncatingTail
superscriptAttributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraph, range: NSMakeRange(0, superscriptAttributedString.length))
return superscriptAttributedString
}
I gave the constraints to the Label like this,
Even though I set number of lines to 0 and no height constraint the label is truncating like this,
But when I don't use this line of code attributedText.addAttribute(NSAttributedStringKey.baselineOffset, value: 2, range: NSMakeRange(0, superScriptString.characters.count)) it is working fine like this,
And also if add * in the middle (without removing attributedText.addAttribute(NSAttributedStringKey.baselineOffset, value: 2, range: NSMakeRange(0, superScriptString.characters.count))) it works fine but just doesn't work if I use it in the beginning of the text,
Screen shot:
And it also works if I increase the font size.
I think there is an issue with NSAttributedString and if not I want to know what is the issue. Could someone please help me.
Your problem is as soon as you assign attributed string you have to re calculate the height. but there is a quick fix which you don't need to calculate it your self. give the label a force line break at the end of your label in which case it has to re calculate the height automatically.
// see the \n at the end of your string that will cause the label to recalculate it's height.
let nameText = "My name is Shreesha and Im an iOS developer. My name is Shreesha and Im an iOS developer."`My name is Shreesha and Im an iOS developer. My name is Shreesha and Im an iOS developer. \n"

iOS 10 and setting custom font for attributed text

I've ported my app to XCode 8 and Swift 3 language syntax. Ever since doing so I've had lots of problems, setting a custom font being my current problem:
var sText = "Hello world, this is some text that I'm going to try to format ok?"
var attText = NSMutableAttributedString(string: sText)
var attrs = [NSFontAttributeName: UIFont(name: "Arial", size: 16)]
attText.addAttributes(attrs, range: NSMakeRange(0, sText.characters.count))
lblLabel1.attributedText = attText
So this code crashes every time with an "unrecognized selector sent to instance". Funny enough, setting other properties (like foreground color) work just fine... Just not fonts. I've tried custom fonts, system fonts, other named fonts... nothing seems to work. Anyone else run into this? Is there something I'm doing wrong here??? This code works fine in XCode 7 and even legacy Swift in XCode 8
Thanks in advance...
James
UIFont(name:) returns an Optional, so you have to unwrap it before use:
var sText = "Hello world, this is some text that I'm going to try to format ok?"
var attText = NSMutableAttributedString(string: sText)
if let arial = UIFont(name: "Arial", size: 16) {
var attrs = [NSFontAttributeName: arial]
attText.addAttributes(attrs, range: NSMakeRange(0, sText.characters.count))
// ...
}

iOS Swift - How to add two different colors in a UILabel

I have two problems regarding the label.
In the first scenario, as I wanted to add two different colors to the label, I did this:
var myMutableString = NSMutableAttributedString()
in viewDidLoad
myMutableString = NSMutableAttributedString(
string: string1,
attributes: [NSFontAttributeName:UIFont(
name: "Montserrat-Light",
size: 12.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName,
value: UIColor.whiteColor(),
range: NSRange(
location:0,
length:25))
myMutableString.addAttribute(NSForegroundColorAttributeName,
value: UIColor.whiteColor(),
range: NSRange(
location:42,
length:3))
myMutableString.addAttribute(NSForegroundColorAttributeName,
value: (UIColor( red: CGFloat(TOSLabelColor[0]), green: CGFloat(TOSLabelColor[1]), blue:CGFloat(TOSLabelColor[2]), alpha: 1.0 )).CGColor
,
range: NSRange(
location:25,
length:16))
bottomLabel.attributedText = myMutableString
This code works fine on mobile running iOS 9 or greater but it doesn't work on iOS 8.4. The app crashes in iOS 8.4.
Also, this code is only suitable for static text/label. The second problem is on some other screen I have a table view in which I have a text like this:
From "America" to "Australia"
I want to display countries in a color and "From" and "to" in a different color. I added on the screen only one label. How can I do that? This is dynamic and I can't implement the previous code.

Resources