Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Dynamic Type @parrots
Slide 2
Slide 2 text
Dynamic Type @parrots
Slide 3
Slide 3 text
Dynamic Type @parrots
Slide 4
Slide 4 text
One of the many things you know you should do, but haven’t gotten to yet. • Dynamic Type • Localization • Voiceover
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
No content
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
~30% of Slopes users use a non- standard font setting.
Slide 10
Slide 10 text
Auto Layout Everywhere Interface Builder First About Slopes
Slide 11
Slide 11 text
Easier than ever!
Slide 12
Slide 12 text
iOS 7: Classes of fonts (“Body”, “Header”, etc) iOS 9: More classes (“Callout”, “Title 1”, “Title 2”)
Slide 13
Slide 13 text
7 Sizes
Slide 14
Slide 14 text
iOS 10: adjustsFontForContentSizeCategory
Slide 15
Slide 15 text
iOS 11: 5 “Accessibility” Sizes
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
No content
Slide 18
Slide 18 text
iOS 11: UIFontMetrics
Slide 19
Slide 19 text
OK, So, How-do?
Slide 20
Slide 20 text
Use a system font size (body / etc) Enable adjustsFontForContentSizeCategory Automagic
Slide 21
Slide 21 text
Doesn’t work with bold
Slide 22
Slide 22 text
let metrics = UIFontMetrics.init(forTextStyle: UIFont.TextStyle.callout) label.font = metrics.scaledFont(for: UIFont.systemFont(ofSize: 16.0)) label. adjustsFontForContentSizeCategory = true Automagic - Custom Font
Slide 23
Slide 23 text
viewDidLoad() { … let metrics = UIFontMetrics.init(forTextStyle: UIFont.TextStyle.callout) label.font = metrics.scaledFont(for: label.font) label. adjustsFontForContentSizeCategory = true Automagic - Custom Font in IB
Slide 24
Slide 24 text
Only do this once per label otherwise
Slide 25
Slide 25 text
UIApplication.shared.preferredContentSizeCategory traitCollection.preferredContentSizeCategory Not Just for Fonts
Slide 26
Slide 26 text
if UIApplication.shared.preferredContentSizeCategory >= .accessibilityMedium { return 2.5 } else if UIApplication.shared.preferredContentSizeCategory >= .extraLarge { return 1.2 } else if UIApplication.shared.preferredContentSizeCategory >= .extraExtraLarge { return 1.8 } return 1.0 Not Just for Fonts
Slide 27
Slide 27 text
let metrics = UIFontMetrics(forTextStyle: UIFont.TextStyle.footnote) let graphLineWidth: CGFloat = metrics.scaledValue(for: 1.0) Not Just for Fonts
Slide 28
Slide 28 text
Won’t automatically update
Slide 29
Slide 29 text
Change graph height Change stroke widths
Slide 30
Slide 30 text
Planning for Expansion
Slide 31
Slide 31 text
No content
Slide 32
Slide 32 text
No content
Slide 33
Slide 33 text
Planning for…
Slide 34
Slide 34 text
Planning for Expansion
Slide 35
Slide 35 text
No content
Slide 36
Slide 36 text
No content
Slide 37
Slide 37 text
func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory { //update whatever is needed } } Responding to Changes
Slide 38
Slide 38 text
UIContentSizeCategoryDidChangeNotification Responding to Changes
Slide 39
Slide 39 text
WWDC 2017 #245: Building Apps with Dynamic Type
Slide 40
Slide 40 text
Tip 1: Accessibility Inspector
Slide 41
Slide 41 text
No content
Slide 42
Slide 42 text
Tip 2: Something is better than nothing.
Slide 43
Slide 43 text
Don’t even have to do every size all at once.
Slide 44
Slide 44 text
80 70%
Slide 45
Slide 45 text
class SlopesApplication: UIApplication { @objc dynamic override var preferredContentSizeCategory: UIContentSizeCategory { get { if super.preferredContentSizeCategory >= .accessibilityMedium { return UIContentSizeCategory.extraExtraExtraLarge } return super.preferredContentSizeCategory } } } Limit Size via UIApplication
Slide 46
Slide 46 text
Don’t even have to do every screen all at once.
Slide 47
Slide 47 text
Tip 3: Use system components They just work!
Slide 48
Slide 48 text
No content
Slide 49
Slide 49 text
Self-Sizing Cells:
Slide 50
Slide 50 text
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension }
Slide 51
Slide 51 text
Built-in Sizes
Slide 52
Slide 52 text
… most of the time
Slide 53
Slide 53 text
Tip 4: Know Thy Sizes
Slide 54
Slide 54 text
UIFontMetrics.init(forTextStyle: UIFont.TextStyle.body)
Slide 55
Slide 55 text
No content
Slide 56
Slide 56 text
Grows Grows Shrinks Doesn’t Shrink
Slide 57
Slide 57 text
func autoSize() { let bodyFontMetrics = UIFontMetrics(forTextStyle: .body) for label in manualResizeBodyLabels ?? [] { label.font = bodyFontMetrics.scaledFont(for: label.font) label.adjustsFontForContentSizeCategory = true } let footnoteFontMetrics = UIFontMetrics(forTextStyle: .footnote) for label in manualResizeFootnoteLabels ?? [] { label.font = footnoteFontMetrics.scaledFont(for: label.font) label.adjustsFontForContentSizeCategory = true } …
Slide 58
Slide 58 text
Tip 5: Plan for Alternate Layouts AKA Stack Views, Stack Views everywhere
Slide 59
Slide 59 text
if UIApplication.shared.preferredContentSizeCategory >= .accessibilityMedium { stack.axis = .vertical stack.spacing = 8.0 } else { stack.axis = .horizontal stack.spacing = 24.0 }
Slide 60
Slide 60 text
No content
Slide 61
Slide 61 text
No content
Slide 62
Slide 62 text
No content
Slide 63
Slide 63 text
Tip 6: Doesn’t have to be pretty, especially at accessibility sizes
Slide 64
Slide 64 text
Use maximums where they make sense .scaledFont(for: label.font, maximumPointSize: 40.0)
Slide 65
Slide 65 text
Tip 7: Pay Attention To Baselines Especially in UITableViews
Slide 66
Slide 66 text
My Text Their Text
Slide 67
Slide 67 text
My Text Their Text Top = Top + 8 Bottom = Bottom + 8
Slide 68
Slide 68 text
No content
Slide 69
Slide 69 text
My Text Their Text My Text Their Text
Slide 70
Slide 70 text
My Text Their Text My Text Their Text Spacing relative to baseline
Slide 71
Slide 71 text
label.firstBaselineAnchor.constraintEqualToSystemSpacingBelow( contentView.to pAnchor, multiplier: 1.0) contentView.bottomAnchor.constraintEqualToSystemSpacingBelow( label.lastBa selineAnchor, multiplier: 1.0)
Slide 72
Slide 72 text
No content
Slide 73
Slide 73 text
No specified height
Slide 74
Slide 74 text
No content
Slide 75
Slide 75 text
No content
Slide 76
Slide 76 text
How’d it go?
Slide 77
Slide 77 text
No content
Slide 78
Slide 78 text
2 weeks
Slide 79
Slide 79 text
Thank You @parrots