Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating animated text effects using NSLayoutManager?

In session 220 (Advanced Text Layouts and Effects with Text Kit) of WWDC 2013 they specifically say NSLayoutManager can be used in conjunction with NSTextStorage and NSTextContainer to create advanced text animations. They don't say how.

I want to use NSLayoutManager/NSTextStorage/NSTextContainer to create custom text animation. To put it simply, I want to animate size and position of individual glyphs and fade and unfade specific glyphs.

There seems to be no dedicated methods nor documentation for animations with NSLayoutManager and the only tutorial on the matter I found is here. However, it shows how to hack NSLayoutManager into animations rather than how to use it the way it is supposed to be used (they create CATextLayer for each individual glyph!).

Can somebody point me to the right direction? I know how to use NSLayoutManager / NSTextStorage / NSTextContainer to render static text. Some demo, showing the principles of animating text with NSLayoutManager would be be perfect. Just to get me started I can figure out details myself.

like image 324
Rasto Avatar asked Jul 11 '15 12:07

Rasto


1 Answers

NSTextContainer、NSLayoutManager、NSTextStorage is new to iOS7:

1) NSTextContainer:

The NSTextContainer class defines a region in which text is laid out. An NSTextContainer object defines rectangular regions, and you can define exclusion paths inside the textcontainer'sboundingrectanglesothattextflowsaroundtheexclusionpathasitislaidout.

2) NSLayoutManager:

An NSLayoutManager object coordinates the layout and display of characters held in an NSTextStorage object. It maps Unicode character codes to glyphs, sets the glyphs in a series of NSTextContainer objects, and displays them in a series of text view objects.

3) NSTextStorage:

NSTextStorage is a semiconcrete subclass of NSMutableAttributedString that manages a set of client NSLayoutManagerobjects,notifyingthemofanychangestoitscharactersorattributessothattheycanrelay and redisplay the text as needed.

We could know NSTextStorage can store and manage UITextView's text,and it is NSMutableAttributedString's subclass.We can add or modify the attributes, so it is a good choice to store and manage UITextView's text.

NSLayoutManager use for manage the content of NSTextStorage's layout.

NSTextContainer provide a rectangle to stash the layouted text.

We can simply use them:

CGRect textViewRect = CGRectInset(self.view.bounds, 10.0, 20.0);

// NSTextContainer
NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(textViewRect.size.width, CGFLOAT_MAX)]; // new in iOS 7.0
container.widthTracksTextView = YES; // Controls whether the receiveradjusts the width of its bounding rectangle when its text view is resized


// NSLayoutManager
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; // new in iOS 7.0
[layoutManager addTextContainer:container];


// NSTextStorage subclass
self.textStorage = [[TextStorage alloc] init]; // new in iOS 7.0
[self.textStorage addLayoutManager:layoutManager];

Firstly is make instance of them, and create thier relationship.You must add NSTextContainer in UITextView by initWithFrame:textContainer: method.

// UITextView
UITextView *newTextView = [[UITextView alloc] initWithFrame:textViewRect textContainer:container];
newTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
newTextView.scrollEnabled = YES;
newTextView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// newTextView.editable = NO;
newTextView.font = [UIFont fontWithName:self.textStorage.fontName size:18.0];
newTextView.dataDetectorTypes = UIDataDetectorTypeAll;
self.textView = newTextView;
[self.view addSubview:self.textView];

If want to use UITextStorage to change text's attributes, you can use:

[_textStorage beginEditing];  // begin edit
[_textStorage endEditing];  // end edit

Between them you can edit text, such as:

[_textStorage beginEditing];
NSDictionary *attrsDic = @{NSTextEffectAttributeName: NSTextEffectLetterpressStyle};
UIKIT_EXTERN NSString *const NSTextEffectAttributeName NS_AVAILABLE_IOS(7_0);          // NSString, default nil: no text effect
NSMutableAttributedString *mutableAttrString = [[NSMutableAttributedString alloc] initWithString:@"Letterpress" attributes:attrsDic];
NSAttributedString *appendAttrString = [[NSAttributedString alloc] initWithString:@" Append:Letterpress"];
[mutableAttrString appendAttributedString:appendAttrString];
[_textStorage setAttributedString:mutableAttrString];
[_textStorage endEditing];

Or change color:

[_textStorage beginEditing];
/* Dynamic Coloring Text */
self.textStorage.bookItem = [[BookItem alloc] initWithBookName:@"Dynamic Coloring.rtf"];
self.textStorage.tokens = @{@"Alice": @{NSForegroundColorAttributeName: [UIColor redColor]},
                            @"Rabbit": @{NSForegroundColorAttributeName: [UIColor greenColor]},
                            DefaultTokenName: @{NSForegroundColorAttributeName: [UIColor blackColor]}
                            };
[_textStorage setAttributedString:_textStorage.bookItem.content];
[_textStorage endEditing];
like image 124
aircraft Avatar answered Nov 04 '22 20:11

aircraft