Is it possible to use NSMutableAttributedString with SKLabelNode? - objective-c

I'm trying to change the kerning on a couple of SKLabelNodes. I tried to use some code from another answer:
NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:#"Please get wider"];
[attributedString addAttribute:NSKernAttributeName value:#5 range:NSMakeRange(10, 5)];
[self.label setAttributedText:attributedString];
This isn't allowed:
[myLabelNode setAttributedText:attributedString];
And this doesn't carry over the changes I made:
myLabelNode.text = attributedString.string;
Is it possible to change kerning on an SKLabelNode?

As of iOS 11, NSAttributedStrings are supported in SKLabelNode. So kerning and other options should now be available to you.

Related

Objective c UIFont systemFontOfSize does not work

I am trying to change text font size with using NSAttributedString. But it's size doesn't change.
NSDictionary *attrDict = #{NSFontAttributeName : [UIFont boldSystemFontOfSize:22], NSForegroundColorAttributeName : [UIColor orangeColor]};
NSAttributedString *newAttString = [[NSAttributedString alloc] initWithString:mytext attributes:attrDict];
[result appendAttributedString:newAttString];
Only text color changes. Size of result string is not 22 and also it is not bold.
Instead of applying the attributes with the alloc, init, try doing it after with something like (with a mutable NSAttributedString):
NSMutableAttributedString *newAtt = [[NSMutableAttributedString alloc] initWithString:mytext]; // Allocate a new NSMutableAttributedString with `mytext`
[newAtt addAttributes:#{NSFontAttributeName : [UIFont boldSystemFontOfSize:20],
NSForegroundColorAttributeName: [UIColor orangeColor]}
range:NSMakeRange(0, [result length])]; // add new attributes for the length of the string `mytext`
[result setAttributedText:newAtt];
This answer would vary depending on what result is, I tested it on a UITextView and it worked fine, there is also an attributedText
property on UILabels.
Hope this helps.
You didn't mention what result means at the end of your code. Are you sure you want to "append" it?
Besides, I use this code for setting fonts
[UIFont fontWithName:#"Arial-BoldMT" size:22.0f]
This can be used to set different fonts and sizes respectively.
Hope this helps:)

Handling UIContentSizeCategoryDidChangeNotification for NSAttributedString in UITextView

I have an NSAttributedString in a UITextView and would like to handle the UIContentSizeCategoryDidChangeNotification when working with Dynamic Type and specifically the text styles. All the examples I've seen (IntroToTextKitDemo) address the case where the font is the same for the whole UI element. Does anyone know how to handle this properly so all the attributes update properly?
Note: I asked this on the developer forums when iOS 7 was under NDA. I'm posting it here because I found a solution and thought others might find it useful.
I found a solution. When handling the notification you need to walk the attributes and look for the text styles and update the font:
- (void)preferredContentSizeChanged:(NSNotification *)aNotification
{
UITextView *textView = <the text view holding your attributed text>
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:textView.attributedText];
NSRange range = NSMakeRange(0, attributedString.length - 1);
// Walk the string's attributes
[attributedString enumerateAttributesInRange:range options:NSAttributedStringEnumerationReverse usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop) {
// Find the font descriptor which is based on the old font size change
NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
UIFont *font = mutableAttributes[#"NSFont"];
UIFontDescriptor *fontDescriptor = font.fontDescriptor;
// Get the text style and get a new font descriptor based on the style and update font size
id styleAttribute = [fontDescriptor objectForKey:UIFontDescriptorTextStyleAttribute];
UIFontDescriptor *newFontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:styleAttribute];
// Get the new font from the new font descriptor and update the font attribute over the range
UIFont *newFont = [UIFont fontWithDescriptor:newFontDescriptor size:0.0];
[attributedString addAttribute:NSFontAttributeName value:newFont range:range];
}];
textView.attributedText = attributedString;
}

Is there a way to do half of a newline?

I'm wondering, is there a way to do half of a new line character (\n) in an NSString in objective C, i.e. so that it only skips about half the space? Or anyway else to accomplish this in an NSString?
Like Wain said, setting NSParagraphStyle on an NSAttributedString might be what you are looking for. UILabel supports NSAttributedStrings in iOS 6, but anything before that you will have to use a third party component. TTTAttributedLabel is very good and well documented.
NSMutableAttributedString* attrStr = [NSMutableAttributedString attributedStringWithString:#"Hello World!"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:24]; //Just a random value, you'll have to play with it till you are hhappy
[attrStr addAttribute:NSParagraphStyleAttributeName
value:style
range:NSMakeRange(0, [myString length])];
label.attributedText = attrStr;
if you end up using TTTAttributedLabel you would use label.text = attrStr; or one of the helper methods (Taken from TTTAttributedLabel docs:
[label setText:text afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange boldRange = [[mutableAttributedString string] rangeOfString:#"ipsum dolar" options:NSCaseInsensitiveSearch];
NSRange strikeRange = [[mutableAttributedString string] rangeOfString:#"sit amet" options:NSCaseInsensitiveSearch];
// Core Text APIs use C functions without a direct bridge to UIFont. See Apple's "Core Text Programming Guide" to learn how to configure string attributes.
UIFont *boldSystemFont = [UIFont boldSystemFontOfSize:14];
CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)boldSystemFont.fontName, boldSystemFont.pointSize, NULL);
if (font) {
[mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)font range:boldRange];
[mutableAttributedString addAttribute:kTTTStrikeOutAttributeName value:[NSNumber numberWithBool:YES] range:strikeRange];
CFRelease(font);
}
return mutableAttributedString;
}];
Also, TTTAttributedLabel has a lineHeightMultiple (between 0.0 and 1.0) property that you might be able to fiddle with to get the desired effect. That way, you'll still be able to use an NSString and not mess with the sometimes ugly NSAttributedString.
While this answer arguably won't help the asker, some historical perspective on the half-linefeed concept may be of general use.
The concept of half-reverse and half-forward linefeeds was useful on teletypes to combine, say, the o and " characters to approximate the German "o umlaut", รถ. The Unix col command recognized ESC-8 (0x1b 0x38) and ESC-9 (0x1b 0x39) as these sequences, respectively, and this standard was adopted by asciitiff.
The printer control language PCL recognized the forward half-linefeed.
An OKI PCL4.5 printer, the OL600e, accepted ESC= (0x1b 0x3d) as half-linefeed, and PCL5 extended that to ESC&= (0x1b 0x26 0x3d).
I'm having difficulty locating older examples.

Displaying NSMutableAttributedString

I have the below code in my app
NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:self.myDisplayTxt];
[string addAttribute:(NSString*)kCTForegroundColorAttributeName
value:(id)[[UIColor redColor] CGColor]
range:NSMakeRange(0,5)];
self.myTextView.text = string;
When assigning the NSMutableAttributedString to UITextView I get the following error:
Incompatible objective c types struct NSMutableAttributedString
expected struct nsstring
So please let me know, how can I display the NSMutableAttributedString in UITextView.
You can try to use some library to do that. As omz wrote, the UITextView does not unfortunatelly support the NSAttributedString.
Maybe this one can help you: https://github.com/enormego/EGOTextView
They say about this library the following:
UITextView replacement with additional support for NSAttributedString.
UPDATE: Based on your clarification in the comment for omz's answer, you can look here:
Underline text inside uitextview
UPDATE 2: In iOS 6 you can use the NSAttributedString out of the box. For example like this:
UIColor *_red=[UIColor redColor];
UIFont *font=[UIFont fontWithName:#"Helvetica-Bold" size:72.0f];
[attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, _stringLength)];
[attString addAttribute:NSStrokeColorAttributeName value:_red range:NSMakeRange(0, _stringLength)];
[attString addAttribute:NSStrokeWidthAttributeName value:[NSNumber numberWithFloat:-3.0] range:NSMakeRange(0, _stringLength)];
You can't, UITextView doesn't support attributed strings. If you really only want to use attributed strings to set the foreground color (as in your example), you could achieve the same by setting the text view's textColor property.
You should assign attributed string via UITextView.attributedText property. UITextView.text accepts NSString or plain text only.
textView.attributedText = attributedString;
See documentation:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextView_Class/index.html#//apple_ref/occ/instp/UITextView/attributedText

Superscripted ordinal suffix in NSString

Is there a way in NSString to output the st, nd, and rd but in a superscripted format? Any known unicode perhaps?
There doesn't seem to be any Unicode characters for this, but it's easy enough to make an NSAttributedString that will do the trick:
NSDictionary * superscriptAttrs = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1]
forKey:NSSuperscriptAttributeName];
NSAttributedString * st = [[NSAttributedString alloc] initWithString:#"st"
attributes:superscriptAttrs];
NSMutableAttributedString * premiere = [[NSMutableAttributedString alloc] initWithString:#"1"];
[premiere appendAttributedString:st];
// Don't forget to release everything when you're done with it!
You might also want to change the font size of the superscript. This is accomplished by including the NSFontAttributeName in the attributes dictionary with an appropriate font object. Note that NSAttributedString is only available on the iPhone in iOS 4.0+, and on the iPad in 3.2+ (see comment).