Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UIKonf '14: TextKit For The Rest Of Us

UIKonf '14: TextKit For The Rest Of Us

TextKit is Apple's way to layout, render and edit text on iOS 7. This new collection of classes enables developers to work with text in unprecedented ways.

After shedding some light on mysterious class names, this talk will highlight a few of those new possibilities. Things you never dared asking for are now are just a few lines of code away.

Max Seelemann

May 14, 2014
Tweet

More Decks by Max Seelemann

Other Decks in Programming

Transcript

  1. UITextView NSString Text User Model View iOS 2 iOS 2

    UITextInput iOS 3.2 Core Text iOS 3.2 NSAttributedString iOS 3.2
  2. UITextView NSString Text User Model View iOS 2 iOS 2

    UITextInput iOS 3.2 Custom View Custom Layout Core Text iOS 3.2 NSAttributedString iOS 3.2
  3. UITextView NSString Text User Model View iOS 2 iOS 2

    UITextInput iOS 3.2 Core Text iOS 3.2 NSAttributedString iOS 3.2 iOS 4
  4. UITextView NSString Text User Model View iOS 2 iOS 2

    UITextInput iOS 3.2 Core Text iOS 3.2 NSAttributedString iOS 3.2 iOS 5
  5. UITextView Text User Model View iOS 2 UITextInput iOS 3.2

    Core Text iOS 3.2 NSAttributedString iOS 3.2 iOS 6
  6. UITextView NSTextStorage Text User Model View Controller NSLayoutManager iOS 7

    iOS 7 NSTextContainer iOS 7 iOS 2 Store Text Control Layout Define Text Area Display + Input
  7. UITextView NSTextStorage NSLayoutManager NSTextContainer textStorage = [NSTextStorage new]; 1 layoutManager

    = [NSLayoutManager new];! [textStorage addLayoutManager: layoutManager]; 2 textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(…, …)];! [layoutManager addTextContainer: textContainer]; 3 textView = [[UITextView alloc] initWithFrame:… textContainer:textContainer]; 4
  8. Class Cluster TKETextStorage NSTextStorage Abstract - string! - attributesAtIndex:effectiveRange:! !

    - replaceCharactersInRange:withString:! - setAttributes:range: NSAttributedString storage
  9. Simple Text Storage TKETextStorage NSAttributedString storage - (NSString *)string {

    return [storage string]; } - (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range { return [storage attributesAtIndex:location effectiveRange:range]; } - (id)init { self = [super init]; ! if (self) { storage = [NSMutableAttributedString new]; } return self; }
  10. Simple Text Storage - (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range { [storage setAttributes:attrs

    range:range]; ! } - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str { [storage replaceCharactersInRange:range withString:str]; ! ! ! } [self edited:NSTextStorageEditedCharacters range:range changeInLength:(NSInteger)str.length - (NSInteger)range.length]; [self edited:NSTextStorageEditedAttributes range:range changeInLength:0];
  11. Code Text Storage TKETextStorage - string! - attributesAtIndex:effectiveRange:! ! -

    replaceCharactersInRange:withString:! - setAttributes:range: Text / Code Attributes TKECodeString storage NSAttributedString cache
  12. Code Text Storage - (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range { [cache setAttributes:attrs

    range:range]; ! [self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; } - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str { [storage replaceCharactersInRange:range withString:str]; [cache replaceCharactersInRange:range withString:str]; ! [self edited:NSTextStorageEditedCharacters range:range changeInLength:(NSInteger)str.length - (NSInteger)range.length]; }
  13. Compute Colors - (void)processEditing { ... // Clean up colors

    ! ! [self.content enumerateCodeInRange:range usingBlock:^(NSRange range, TKECodeType type) { ! [self addAttribute:NSForegroundColorAttributeName value:[self textColorForCodeType: type] range:range]; ! }]; ! [super processEditing]; } CodeString knows code TextStorage maps colors
  14. NSTextContainer Vivamus et turpis in dui blandit pulvinar nec dignissim

    diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum enim. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus hendrerit venenatis libero, vitae sodales lacus elementum eget. Duis sit amet risus ac nunc blandit lobortis vel sed nibh. Suspendisse laoreet odio ac ligula aliquam scelerisque. Nulla volutpat consectetur sem tincidunt cursus. In ac justo in libero. Fusce tincidunt erat sit amet magna porttitor nec iaculis diam varius. Aliquam eget odio leo. Sed faucibus, libero non consectetur tristique, metus leo tempus libero, quis ornare felis purus in odio. Proin metus arcu, dictum id faucibus gravida, pulvinar ut metus. Mauris nisl sapien, cursus nec auctor quis, bibendum vitae. Etiam id nisl libero, nec consequat dolor. Fusce id ornare enim. Praesent viverra rutrum erat, eu gravida erat scelerisque at. Donec sed lectus leo. Nunc vel volutpat libero. Maecenas euismod molestie neque non feugiat. Vestibulum hendrerit lorem leo, condimentum imperdiet velit. Quisque urna nisi, faucibus id Vivamus et turpis in dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum enim. Cum sociis natoque penatibus et magnis dis p a r t u r i e n t montes, nascetur r i d i c u l u s m u s . P h a s e l l u s hendrerit venenatis libero, v i t a e s o d a l e s l a c u s elementum eget. Duis sit amet risus ac nunc b l a n d i t lobortis vel sed nibh. Suspendisse laoreet o d i o a c ligula aliquam scelerisque. Nulla volutpat consectetur sem tincidunt cursus. In ac justo in libero. Fusce tincidunt erat sit amet magna porttitor nec iaculis diam varius. Aliquam eget odio leo. Sed faucibus, libero non consectetur tristique, metus leo tempus libero, quis ornare felis purus in odio. Proin metus arcu, dictum id faucibus gravida, pulvinar ut metus. Mauris nisl sapien, cursus nec auctor quis, bibendum vitae. Etiam id nisl libero, nec consequat dolor. Fusce id ornare enim. Praesent viverra rutrum erat, eu gravida erat scelerisque at. Donec sed Vivamus et turpis in dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, c o n s e q u a t v e l l u c t u s i n , consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. S u s p e n d i s s e p o t e n t i . Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum enim. C u m s o c i i s n a t o q u e penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus hendrerit venenatis libero, v i t a e s o d a l e s l a c u s elementum eget. Duis sit amet risus ac nunc blandit l o b o r t i s v e l s e d n i b h . Suspendisse laoreet odio ac ligula aliquam scelerisque. Nulla volutpat consectetur sem tincidunt cursus. In ac justo in libero. Fusce tincidunt erat sit amet magna porttitor nec iaculis diam varius. Aliquam eget odio leo. Sed faucibus, Vivamus et turpis in dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum enim. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus hendrerit venenatis libero, vitae sodales lacus elementum eget. Duis sit amet risus ac nunc blandit lobortis vel sed nibh. Suspendisse laoreet odio ac ligula aliquam scelerisque. Nulla volutpat consectetur sem tincidunt cursus. In ac justo in libero. Fusce tincidunt erat sit amet magna porttitor nec iaculis diam varius. Aliquam eget odio leo. Sed faucibus, libero non consectetur tristique, metus leo tempus libero, quis ornare felis purus in odio. Proin metus arcu, dictum id faucibus gravida, pulvinar ut metus. Mauris nisl sapien, cursus nec auctor quis, bibendum vitae. Define Text Area
  15. Insetting Text Container - (CGRect)lineFragmentRectForProposedRect:(CGRect)proposedRect atIndex:(NSUInteger)characterIndex writingDirection:(NSWritingDirection)baseWritingDirection remainingRect:(CGRect *)remainingRect {

    CGRect rect = [super lineFragmentRectForProposedRect:proposedRect atIndex:characterIndex writingDirection:baseWritingDirection remainingRect:remainingRect]; ! rect.origin.x += inset; rect.size.width -= inset; ! return rect; } Hangs the text layout
  16. Typesetting View (UITextContainer) Text (NSTextStorage) (NSTypesetter) Vivamus et turpis in

    dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere Line Fragment Rect Characters to Glyphs A → A Text Attributes Store Layout (NSLayoutManager)
  17. Typesetting View (UITextContainer) Text (NSTextStorage) (NSTypesetter) Vivamus et turpis in

    dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere Line Fragment Rect Characters to Glyphs A → A Text Attributes Store Layout (NSLayoutManager) UIKonf in Berlin
  18. Typesetting View (UITextContainer) Text (NSTextStorage) (NSTypesetter) Vivamus et turpis in

    dui blandit pulvinar nec dignissim diam. Nulla scelerisque posuere viverra. Quisque nibh nunc, consequat vel luctus in, consectetur vitae mauris. Nunc lacinia malesuada mauris, sed egestas nunc fermentum nec. Suspendisse potenti. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere Line Fragment Rect Characters to Glyphs A → A Text Attributes Store Layout (NSLayoutManager) UIKonf in Berlin Shorten Line Offset Line
  19. Offsetting Line Fragment - (void)setLineFragmentRect:(CGRect)fragmentRect forGlyphRange:(NSRange)glyphRange usedRect:(CGRect)usedRect { fragmentRect.origin.x +=

    inset; usedRect.origin.x += inset; [super setLineFragmentRect:fragmentRect forGlyphRange:glyphRange usedRect:usedRect]; }
  20. Paragraph numbers - (void)drawBackgroundForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin { [super drawBackgroundForGlyphRange:glyphsToShow atPoint:origin]; !

    ! ! ! ! ! ! ! ! ! ! ! ! ! ! } // Enumerate all lines NSUInteger glyphIndex = glyphRange.location; while (glyphIndex < NSMaxRange(glyphRange)) { ! ! ! ! ! ! ! ! // Advance glyphIndex = NSMaxRange(glyphLineRange); } NSRange glyphLineRange; CGRect lineRect = [self lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:&glyphLineRange]; ! // Drawing ...
  21. Model View Controller Store Text Control Layout Define Text Area

    Display + Input UITextView NSTextStorage NSLayoutManager NSTextContainer
  22. • Indented Line Wrap • Dynamic Line Height • Dynamic

    Tab Size github.com/macguru/TextKitEditor TextKitEditor on GitHub Max Seelemann – @macguru17