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

Hello TextKit!

Hello TextKit!

A introductory talk about TextKit that I gave during 2014 Istanbul Tech Talks. Here's the video: http://www.youtube.com/watch?v=s2uRKXVGtMg

Max Seelemann

April 28, 2014
Tweet

More Decks by Max Seelemann

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. NSTextStorage Store Text NSTextContainer Define Text Area + Attributes Model

    NSLayoutManager Control Layout Controller UITextView Display + Input View
  4. Class Cluster TKETextStorage NSTextStorage Abstract - string - attributesAtIndex:effectiveRange: -

    replaceCharactersInRange:withString: - setAttributes:range: NSAttributedString storage
  5. 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; }
  6. 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];
  7. Code Text Storage TKETextStorage - string - attributesAtIndex:effectiveRange: - replaceCharactersInRange:withString:

    - setAttributes:range: Text / Code Attributes TKECodeString storage NSAttributedString cache
  8. 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]; }
  9. 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
  10. 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
  11. 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
  12. NSTextContainer NSTextStorage NSLayoutManager Control Layout UITextView Define Text Area Store

    Text Display + Input NSGlyphGenerator NSTypesetter Create Layout Store Layout Control Layout NSLayoutManager Delegate
  13. 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) Test in Istanbul Shorten Line Offset Line
  14. 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]; }
  15. 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 ...
  16. • Indented Line Wrap • Dynamic Line Height • Dynamic

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