I want my text strike through extend on whitespace - ios

I use NSAttributeString to set strike through on my text, I want it extend on whitespace.
I already set the correct range, but the strike through only cover the text characters. The strike through is ignore the whitespace unless I add some non-empty text before and after it.
How can I make the strike through extend on whitespace without extra text?

I have come across the same problem today, and neither existing answers gave me a solution I felt was as straightforward as it should be. After some research, I found a more concise solution using Unicode characters.
Padding each side of your text with one or more non-breaking Unicode space characters (U+00A0) extends the line as desired:
let attributedText = NSAttributedString(
string: "\u{00A0}\(someText)\u{00A0}",
attributes: [.strikethroughStyle: NSUnderlineStyle.single.rawValue]
)

I haven't found any solution but with your last option means adding first and last character as . with space you can try one thing. Either set the NSForegroundColorAttributeName of that first and last character to your background color of label or set the NSFontAttributeName with UIFont.systemFont(ofSize: 0.1). So it will be goes like this. You haven't specify your answer language so i'm posting answer in latest Swift 3.
let attributedText = NSMutableAttributedString(string: self.lbl.text!)
attributedText.addAttributes([NSStrikethroughStyleAttributeName: 2], range: NSMakeRange(0, self.lbl.text!.characters.count))
self.lbl.attributedText = attributedText
Before using NSForegroundColorAttributeName & NSFontAttributeName
Now you can use either NSForegroundColorAttributeName or NSFontAttributeName to hide first and last dot(.) character.
let attributedText = NSMutableAttributedString(string: self.lbl.text!)
attributedText.addAttributes([NSStrikethroughStyleAttributeName: 2], range: NSMakeRange(0, self.lbl.text!.characters.count))
attributedText.addAttributes([NSForegroundColorAttributeName: UIColor.white], range: NSMakeRange(0, 1))
attributedText.addAttributes([NSForegroundColorAttributeName: UIColor.white], range: NSMakeRange(self.lbl.text!.characters.count - 1, 1))
//Or either Set NSFontAttributeName instead of NSForegroundColorAttributeName
//attributedText.addAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 0.1)], range: NSMakeRange(0, 1))
//attributedText.addAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 0.1)], range: NSMakeRange(self.lbl.text!.characters.count - 1, 1))
self.lbl.attributedText = attributedText
After using NSForegroundColorAttributeName or NSFontAttributeName

For people coming to this question who only want a horizontal line through whitespace, this is the way to do it (Swift 4):
let line = String(repeating: "\u{23AF}", count: 10)

Related

UILabel Attributed Text doesn't fill entire line before starting a new line

As you can see from the image, the background of the UILabel is set to yellow. The attributed text does not use all the space before wrapping to the next line ("at" should be in the first line). Any way to fix it?
The label is constructed as follows. It is inside a UICollectionView header, and positioned by autolayout
let astring = NSMutableAttributedString(string: "You asked friends, and people at ")
astring.append(NSAttributedString(string:"Pittsburgh",
attributes: [.font: UIFont.boldSystemFont(ofSize: 15)]))
let label = UILabel()
label.attributedText = astring
Yes, odd bug...
One work-around, although I haven't done any testing on it except to see that it works in your case.
Append a "no-width space" character at the end:
let astring = NSMutableAttributedString(string: "You asked friends, and people at ")
astring.append(NSAttributedString(string:"Pittsburgh",
attributes: [.font: UIFont.boldSystemFont(ofSize: 15)]))
astring.append(NSAttributedString(string:"\u{200b}",
attributes: [.font: UIFont.systemFont(ofSize: 15)]))
Result:
Append the ""\u{200b}" in Attributed String in End . hope it it will work ,

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"

What is UTF-8 character for "previous arrow", same as system back in UINavigationItem?

I just couldn't find utf-8 encoding for character like following:
I think that it is quite possible to create this in code, as a composed character from two dashes: / and \, but I do not know what characters to compose.
Maybe U+003C
print("\u{003C}") // <
Possibly U+2039.
print("\u{2039}") // ‹
Or U+276E.
print("\u{276E}") // ❮
I'm not certain if this will work for a navigation item, but you could make use of NSAttributedString to have string with different sizes of the substrings within it. This is described in detail in this great answer:
How do I make an attributed string using Swift?
As an example for your case:
let myAttributeBack = [ NSFontAttributeName: UIFont(name: "HelveticaNeue-UltraLight", size: 30.0)!]
let attrString = NSMutableAttributedString(string: "\u{276E} ", attributes: myAttributeBack)
let myAttributeText = [ NSFontAttributeName: UIFont(name: "HelveticaNeue-UltraLight", size: 15.0)!]
let backString = NSAttributedString(string: "back", attributes: myAttributeText)
attrString.appendAttributedString(backString)
myLabel.attributedText = attrString
However, as you write below, perhaps it's not possible to use attributed strings for title of a navigation bar item. Then I'd assume that the navigation bar example you showed above simply contains an image with the back bracket and a string "back" for the title text.
Is it this:
〈
The code is U+276C.
see https://en.wiktionary.org/wiki/%E3%80%88

Dynamically setting a storyboard-generated UILabel's attributed string with two different fonts (Swift)

I have a UILabel in my storyboard, and I have an #IBOutlet to it in my controller. In my viewDidLoad, I am setting its attributed text with two different font sizes.
let str1 = NSMutableAttributedString(string: "first", attributes: [NSFontAttributeName: UIFont.systemFontOfSize(15.0)])
let str2 = NSMutableAttributedString(string: "second", attributes: [NSFontAttributeName: UIFont.systemFontOfSize(10.0)])
str1.appendAttributedString(str2)
myLabel.attributedText = str1
Unfortunately, when I run the app, I can see the "firstsecond" string, but all in the same size (str1's 15-point font). Why is str2's 10-point font not being set?
Thanks in advance.
You have to use addAttribute(...) to apply multiple attributes to the same string.
let first = "first"
let second = "second"
let string = NSMutableAttributedString(string: first + second)
string.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(15), range: NSMakeRange(0, first.characters.count))
string.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(10), range: NSMakeRange(first.characters.count, second.characters.count))
myLabel.attributedText = string
The documentation for UILabel's attributedText property states:
assigning a new value updates the values in the font, textColor, and
other style-related properties so that they reflect the style
information starting at location 0 in the attributed string.
So whatever the style information is at location 0, that's what the label's going to be. That's why you're only seeing str1's 15 point font.

NSAttributedString superscript styling

I want to superscript all the instances of ® character in a block of text (legal disclaimer, naturally ;)) and the default way NSAttributedString is not very good.
If I just let the character be and only use unmodified NSString, it is rendered the same size as a capital letter and is placed approximately at the baseline. If I add the superscript attribute to NSAttributedString as follows:
[attrStr setAttributes:#{(NSString *)kCTSuperscriptAttributeName : #1} range:NSMakeRange(locationOfReg, 1)];
The character is lifted off the baseline, its size is unchanged, but the line spacing is now affected because the raised character would otherwise intrude on the line above.
To illustrate:
I created this image in Photoshop where the desired position was achieved by reducing the size of the character and shifting the baseline. I know how to change the font size in iOS, but changing the baseline seems trickier. Any suggestions on how to achieve this?
Edit: I suppose I could use the superscript attribute as a way to shift the baseline up. Now it would be great to figure out a way to get the current font size and subsequently reduce it to allow the same method to be used on blocks of text of different size.
The following code seems to do the trick:
UIFont *fnt = [UIFont fontWithName:#"Helvetica" size:20.0];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:#"GGG®GGG"
attributes:#{NSFontAttributeName: [fnt fontWithSize:20]}];
[attributedString setAttributes:#{NSFontAttributeName : [fnt fontWithSize:10]
, NSBaselineOffsetAttributeName : #10} range:NSMakeRange(3, 1)];
Swift version:
let fnt = UIFont(name:"Helvetica", size:20.0)
let attributedString = NSMutableAttributedString(string:"GGG®GGG", attributes:[NSFontAttributeName : fnt!])
attributedString.setAttributes([NSFontAttributeName : fnt!.fontWithSize(10), NSBaselineOffsetAttributeName: 10], range: NSRange(location: 3, length: 1))
Swift 5
let fnt = UIFont(name:"Helvetica", size:20.0)
let attributedString = NSMutableAttributedString(string:"2.099", attributes:[NSAttributedString.Key.font : fnt!])
attributedString.setAttributes([NSAttributedString.Key.font : fnt!.withSize(10), NSAttributedString.Key.baselineOffset: 10], range: NSRange(location: 4, length: 1))
Swift 4.2
In my example I want to subscript one instance of infinity symbol so my label's title will look like this:
let font = UIFont(name: "Helvetica", size: 14.0)
let attributedString = NSMutableAttributedString(string: "Solids(ΔE∞)•G7®", attributes: [NSAttributedStringKey.font : font!])
attributedString.setAttributes([NSAttributedStringKey.baselineOffset: -5], range: NSRange(location: 9, length: 1))
solidsLbl.attributedText = attributedString

Resources