how to set attributes in NSAttributedString in iOS? - ios

I'm trying to set the infamous NSFontAttributeName property of an NSAttributedString in iOS but it just doesn't seem to work:
first off, none of the NS constants seem defined for iOS
I read somewhere that I could instead work around it by passing
the CoreText consts instead. Fine... but still, The attribute
expects an NSFont and I'm stuck with UIFont or CTFontRef, neither of
which seems to work:
this doesn't work:
CTFontRef ctFont = CTFontCreateWithName((CFStringRef)[UIFont boldSystemFontOfSize:16].fontName, [UIFont boldSystemFontOfSize:16].pointSize, NULL);
[myAttString addAttribute:(NSString*)kCTFontNameAttribute
value:(id)ctFont
range:NSMakeRange(0, myAttString.length-1)];
this doesn't work:
[myAttString addAttribute:(NSString*)kCTFontNameAttribute
value:[UIFont boldSystemFontOfSize:16]
range:NSMakeRange(0, myAttString.length-1)];
Is there anyway to make this work?

I found it!
basically, turns out the string constant for the dictionary key I should been using is kCTFontAttributeName
This whole thing is a show...

The NS constants and full attributedString support will be there. Not yet in iOS5 though.
The CoreText constants do work and CTFontRef is the way I use it as well. The first block of your code should work. Can you verify your other bits of code that the problem ain't elsewhere.

do this way:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attributes = [NSParagraphStyleAttributeName : paragraphStyle,
NSFontAttributeName : UIFont.systemFont(ofSize: 24.0),
NSForegroundColorAttributeName : UIColor.blue,
]
let attrString = NSAttributedString(string: "Stop\nall Dance",
attributes: attributes)

Related

I want my text strike through extend on whitespace

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)

drawInRect text alignment using Swift

I am trying to put some text on top of an image that would be in the center of a CGRect which would be on top of that image. Here is a bit of code:
let textColor: UIColor = UIColor.whiteColor()
let textFont: UIFont = UIFont(name: "Helvetica Bold", size: 17
)!
let textAlignment = NSTextAlignment.Center
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
NSTextAlignment: textAlignment
]
myString.drawInRect(rect, withAttributes: textFontAttributes)
The problem is in the text alignment. When I write it like this I get an error:
Type of expression is ambiguous without more context
When I set key and value types to [String : AnyObject] the compiler complains again:
Cannot convert value of type 'NSTextAlignment.Type' to expected dictionary key type 'String'
Which I understand. I researched this for like two hours and haven't found any up to date solution and not single one how cloud one write this using Swift.
NSTextAlignment isn't a valid key. Note how the other keys end in Name. See the docs for NSFontAttributeName and NSForegroundColorAttributeName to see the list of valid keys.
Instead of NSTextAlignment you need to use NSParagraphStyleAttributeName which requires that you create an instance of NSParagraphStyle. That is where you set the alignment to .Center.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Center
The text alignment belongs to the paragraph style. Create a NSMutableParagraphStyle instance and pass it with key NSParagraphStyleAttributeName to the attributes.
let style = NSMutableParagraphStyle()
style.alignment = .Center
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: style
]

Way stroke outline number using swift

is there anyway to draw or stroke a number using swift for iOS? The number has to be in the outline style. Thanks in advance.
Use an NSAttributedString. UITextField can display attributed strings using the attributedText property.
let number = 5 // Whatever number you are looking to output
let font = UIFont.systemFontOfSize(12.0)
let attribs = [
NSForegroundColorAttributeName: UIColor.whiteColor(),
NSStrokeColorAttributeName: UIColor.blackColor(),
NSFontAttributeName: font,
NSStrokeWidthAttributeName: 1.0
]
let outlinedNumber = NSAttributedString(string: "\(number)", attributes: attribs)
Play with the various attributes to get the effect you want.

WatchKit : Attributed string 'String ' contains NSFontAttributeName that isn't a UIFont (SanFranciscoDisplay-Light). Removed

I am getting the following error
Attributed string 'String ' contains NSFontAttributeName that isn't a
UIFont (SanFranciscoDisplay-Light). Removed
Which doesn't make any sense to me because it should be a valid font according to this. http://iosfonts.com. Here is my code.
atrString = NSAttributedString(string: atrString.string, attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(),
NSFontAttributeName:"SanFranciscoDisplay-Light"])
I am trying to access the San Francisco font from my watch kit code. Any tips or suggestions are appreciated.
NSFontAttributeName is a key that should contain a value of type UIFont.
Try UIFont(name: "SanFranciscoDisplay-Light", size: 25) with the size being whatever font size you want.
atrString = NSAttributedString(string: atrString.string, attributes: [NSForegroundColorAttributeName: UIColor.lightGrayColor(), NSFontAttributeName:UIFont(name: "SanFranciscoDisplay-Light", size: 25)])

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