Hi performance table views with QuartzCore and CoreText

63
Hi-Performance Table Views with QuartzCore and CoreText Mugunth Kumar Beginners guide to an advanced concept Steinlogic Consulting and Training Pte Ltd

description

QuartzCore and CoreText can be used to render text and graphics faster than UIKit elements. In this presentation you will learn some of these tricks

Transcript of Hi performance table views with QuartzCore and CoreText

Page 1: Hi performance table views with QuartzCore and CoreText

Hi-Performance Table Views with QuartzCore

and CoreText

Mugunth Kumar

Beginners guide to an advanced concept

Steinlogic Consulting and Training Pte Ltd

Page 2: Hi performance table views with QuartzCore and CoreText

About me

Page 3: Hi performance table views with QuartzCore and CoreText

About me

• Author of the iOS 5, iOS 6 Programming: Pushing the Limits book - Reached the top 100 books in Amazon’s Computer and Technology books list

• Trainer - Conducts training on iOS programming at iOSTraining.sg.

• Developer

• MKNetworkKit (1200+ watchers)

• MKStoreKit (700+ watchers)

• Several other “minor” projects with 200+ watchers

• Clients include startups in Singapore like Squiryl, Found and MNC’s including Microsoft Redmond, Oracle and such.

Page 4: Hi performance table views with QuartzCore and CoreText

Why?

• What makes apps pleasant to use?

• Fast scrolling

• Why?

Page 5: Hi performance table views with QuartzCore and CoreText

Why?

Page 6: Hi performance table views with QuartzCore and CoreText

Why?

• iPhone is a direct manipulation device

Page 7: Hi performance table views with QuartzCore and CoreText

Why?

• iPhone is a direct manipulation device

• iPhone screen is closer to your eye than your HDTV or your computer monitor

Page 8: Hi performance table views with QuartzCore and CoreText

Why?

• iPhone is a direct manipulation device

• iPhone screen is closer to your eye than your HDTV or your computer monitor

• 60 frames per second = 16.66ms per frame

Page 9: Hi performance table views with QuartzCore and CoreText

Why?

• iPhone is a direct manipulation device

• iPhone screen is closer to your eye than your HDTV or your computer monitor

• 60 frames per second = 16.66ms per frame

• Anything less, you will get a headache

Page 10: Hi performance table views with QuartzCore and CoreText

Agenda

Page 11: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

Page 12: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

• Three different methods

Page 13: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

• Three different methods

• Pros and Cons

Page 14: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

• Three different methods

• Pros and Cons

• QuartzCore/CoreText introduction

Page 15: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

• Three different methods

• Pros and Cons

• QuartzCore/CoreText introduction

• A simple table view cell example

Page 16: Hi performance table views with QuartzCore and CoreText

Agenda

• Why?

• Three different methods

• Pros and Cons

• QuartzCore/CoreText introduction

• A simple table view cell example

• What else can you build? - Facebook style news feed

Page 17: Hi performance table views with QuartzCore and CoreText

Compositing Table View Cells

• UITableViewCell

• Subviews (UILabel, UIImageView)

Page 18: Hi performance table views with QuartzCore and CoreText

Pros/Cons

Page 19: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Programmatically easy

• Fast for compositing images

• Built in cells are rendered differently

Page 20: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Programmatically easy

• Fast for compositing images

• Built in cells are rendered differently

• Drawbacks

• Slow for text based tables

Page 21: Hi performance table views with QuartzCore and CoreText

Direct Drawing

• UITableViewCell drawRect

• NSString -drawInRect, drawAtPoint

• UIImage -drawInRect, drawAtPoint

Page 22: Hi performance table views with QuartzCore and CoreText

Pros/Cons

Page 23: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Fast

• Really fast!

Page 24: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Fast

• Really fast!

• Drawbacks

• Difficult (Annoyingly complex to build complex layouts)

• CGContextDrawImage is really slow compared to using UIImageView

Page 25: Hi performance table views with QuartzCore and CoreText

Hybrid

• A mix of drawRect + UIImageViews

Page 26: Hi performance table views with QuartzCore and CoreText

Cons

Page 27: Hi performance table views with QuartzCore and CoreText

Cons

• Still cannot render shadows around images views

Page 28: Hi performance table views with QuartzCore and CoreText

Cons

• Still cannot render shadows around images views

self.view.layer.masksToBounds = NO; self.view.layer.shadowColor = [UIColor blackColor].CGColor; self.view.layer.shadowOffset = CGSizeMake(0.0f, -1.0f); self.view.layer.shadowOpacity = 0.5f; self.view.layer.shadowRadius = 1.0f;

Page 29: Hi performance table views with QuartzCore and CoreText

Cons

• Still cannot render shadows around images views

self.view.layer.masksToBounds = NO; self.view.layer.shadowColor = [UIColor blackColor].CGColor; self.view.layer.shadowOffset = CGSizeMake(0.0f, -1.0f); self.view.layer.shadowOpacity = 0.5f; self.view.layer.shadowRadius = 1.0f;

• The above code is dog slow.

• Good for views, very bad for table view cells or collection view cells

Page 30: Hi performance table views with QuartzCore and CoreText

Is there a better way?

• QuartzCore.framework

• CoreText.framework

Page 31: Hi performance table views with QuartzCore and CoreText

Pros/Cons

Page 32: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Fast

• Can render text and image within our 16ms deadline

• Rendering highly customized text is hard

Page 33: Hi performance table views with QuartzCore and CoreText

Pros/Cons

• Advantages

• Fast

• Can render text and image within our 16ms deadline

• Rendering highly customized text is hard

This is BOLD and this is in italics.

Page 34: Hi performance table views with QuartzCore and CoreText

QuartzCore

• CALayer

• CATextLayer

• CAGradientLayer

• CAShapeLayer

Page 35: Hi performance table views with QuartzCore and CoreText

CoreText

• NSAttributedString

• NSMutableAttributedString

• UIBezierPath

Page 36: Hi performance table views with QuartzCore and CoreText

Composition

@interface SCTCoreTextCell

@property (strong, nonatomic) CATextLayer *nameTextLayer;@property (strong, nonatomic) CATextLayer *timeTextLayer;@property (strong, nonatomic) CALayer *avatarImageLayer;@property (strong, nonatomic) CALayer *avatarImageShadowLayer;@property (strong, nonatomic) CATextLayer *descriptionTextLayer;

@end

Page 37: Hi performance table views with QuartzCore and CoreText

CALayer - Images

self.backgroundLayer = [CALayer layer]; self.backgroundLayer.frame = CGRectMake(0, 0, 320, 150); self.backgroundLayer.contentsScale = [[UIScreen mainScreen] scale]; self.backgroundLayer.actions = [NSDictionary actionsDictionary]; self.backgroundLayer.contents = (id) backgroundImage.CGImage;

self.backgroundLayer.contentsCenter = CGRectMake(1.0/backgroundImage.size.width, 8.0/backgroundImage.size.height, 1.0/backgroundImage.size.width,1.0/backgroundImage.size.height); self.backgroundLayer.contentsGravity = kCAGravityResize;

[self.contentView.layer addSublayer:self.backgroundLayer];

Page 38: Hi performance table views with QuartzCore and CoreText

CATextLayer - Text

self.nameTextLayer = [CATextLayer layer]; self.nameTextLayer.frame = CGRectMake(65, 3, 240, 21); self.nameTextLayer.alignmentMode = kCAAlignmentLeft; self.nameTextLayer.wrapped = YES; self.nameTextLayer.contentsScale = [[UIScreen mainScreen] scale]; self.nameTextLayer.actions = [NSDictionary actionsDictionary]; [self.contentView.layer addSublayer:self.nameTextLayer];

Page 39: Hi performance table views with QuartzCore and CoreText

Composition

+(NSDictionary*) actionsDictionary { return @{ @"onOrderIn" : [NSNull null], @"onOrderOut" : [NSNull null], @"sublayers" : [NSNull null], @"contents" : [NSNull null], @"position" : [NSNull null], @"bounds" : [NSNull null], @"onLayout" : [NSNull null], @"hidden" : [NSNull null], }; });}

Page 40: Hi performance table views with QuartzCore and CoreText

Contents

Page 41: Hi performance table views with QuartzCore and CoreText

Contents

• CALayer

• Mostly Images

• Rendering a graphics context in background

Page 42: Hi performance table views with QuartzCore and CoreText

Contents

• CALayer

• Mostly Images

• Rendering a graphics context in background

Page 43: Hi performance table views with QuartzCore and CoreText

Contents

• CALayer

• Mostly Images

• Rendering a graphics context in background

• CAGradientLayer

• Adding gradient backgrounds

Page 44: Hi performance table views with QuartzCore and CoreText

Contents

Page 45: Hi performance table views with QuartzCore and CoreText

Contents

• CAShapeLayer

• Mostly Paths

• Use UIBezierPath to create a path

Page 46: Hi performance table views with QuartzCore and CoreText

Contents

• CAShapeLayer

• Mostly Paths

• Use UIBezierPath to create a path

Page 47: Hi performance table views with QuartzCore and CoreText

Contents

• CAShapeLayer

• Mostly Paths

• Use UIBezierPath to create a path

• CATextLayer (Most useful + complicated)

• Text (NSAttributedString)

Page 48: Hi performance table views with QuartzCore and CoreText

NSAttributedString

• The basic building block for complex text rendering

• NSAttributedString = NSString + Attributes Dictionary

Page 49: Hi performance table views with QuartzCore and CoreText

Demo 1 - Simple Bold

Page 50: Hi performance table views with QuartzCore and CoreText

Composition-(void) setText { CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)[UIFont boldSystemFontOfSize:17].fontName, [UIFont boldSystemFontOfSize:17].pointSize, NULL); NSDictionary *boldAttributes = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)ctBoldFont, (id)kCTFontAttributeName, [UIColor blackColor].CGColor, (id)kCTForegroundColorAttributeName, nil]; CFRelease(ctBoldFont);

CTFontRef ctNormalFont = CTFontCreateWithName((__bridge CFStringRef)[UIFont systemFontOfSize:16].fontName, [UIFont systemFontOfSize:16].pointSize, NULL); NSDictionary *normalAttributes = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)ctNormalFont, (id)kCTFontAttributeName, [UIColor blackColor].CGColor, (id)kCTForegroundColorAttributeName, nil]; CFRelease(ctNormalFont);

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"iOS Dev Scout is a AWESOME iOS group!" attributes:normalAttributes]; [string addAttributes:boldAttributes range:NSMakeRange(19, 7)]; self.textLayer.string = string;}

Page 51: Hi performance table views with QuartzCore and CoreText

Composition

CTFontRef ctNormalFont = CTFontCreateWithName((__bridge CFStringRef)[UIFont systemFontOfSize:16].fontName, [UIFont systemFontOfSize:16].pointSize, NULL); NSDictionary *normalAttributes = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)ctNormalFont, (id)kCTFontAttributeName, [UIColor blackColor].CGColor, (id)kCTForegroundColorAttributeName, nil]; CFRelease(ctNormalFont);

Page 52: Hi performance table views with QuartzCore and CoreText

Composition

CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)[UIFont boldSystemFontOfSize:17].fontName, [UIFont boldSystemFontOfSize:17].pointSize, NULL); NSDictionary *boldAttributes = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)ctBoldFont, (id)kCTFontAttributeName, [UIColor blackColor].CGColor, (id)kCTForegroundColorAttributeName, nil]; CFRelease(ctBoldFont);

Page 53: Hi performance table views with QuartzCore and CoreText

Composition

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"iOS Dev Scout is a AWESOME iOS group!" attributes:normalAttributes]; [string addAttributes:boldAttributes range:NSMakeRange(19, 7)]; self.textLayer.string = string;

Page 54: Hi performance table views with QuartzCore and CoreText

What did we use?

• kCTForegroundColorAttributeName

• kCTFontAttributeName

Page 55: Hi performance table views with QuartzCore and CoreText

What else available?

• kCTCharacterShapeAttributeName

• kCTKernAttributeName

• kCTLigatureAttributeName

• kCTParagraphStyleAttributeName

• kCTStrokeWidthAttributeName

• kCTStrokeColorAttributeName

Page 56: Hi performance table views with QuartzCore and CoreText

What else available?

• kCTSuperscriptAttributeName

• kCTUnderlineColorAttributeName

• kCTUnderlineStyleAttributeName

• kCTVerticalFormsAttributeName

• kCTGlyphInfoAttributeName

• kCTRunDelegateAttributeName

• NSLinkAttributeName (only on Mac)

Page 57: Hi performance table views with QuartzCore and CoreText

What else available?

• And that is just text.

• Lot more for image rendering

• Even lot more for animation

• NSLinkAttributeName not available on iOS. You should look at OHAttributedLabel or play around with UIButtons

Page 58: Hi performance table views with QuartzCore and CoreText

Demo 2 - Facebook

Page 59: Hi performance table views with QuartzCore and CoreText

Performance tips

Page 60: Hi performance table views with QuartzCore and CoreText

Performance tips

• Use dispatch_once for almost any “constants”

• UIFont, UIBezierPath, UIColor etc.,

Page 61: Hi performance table views with QuartzCore and CoreText

Performance tips

• Use dispatch_once for almost any “constants”

• UIFont, UIBezierPath, UIColor etc.,

Page 62: Hi performance table views with QuartzCore and CoreText

Performance tips

• Use dispatch_once for almost any “constants”

• UIFont, UIBezierPath, UIColor etc.,

• Use strptime* methods instead of NSDateFormatter

• No support for locale, but crazy fast

Page 63: Hi performance table views with QuartzCore and CoreText

Thanks@mugunthkumar

[email protected]

iostraining.sg

Available for consulting services

iOS App Development API DesignMobile UX