Speaker: Luke Hiesterman, UIKit Engineer
- App lifecycle
- Views and view controllers
- Auto layout
- Table and collection views
- Peak performance for your app
- Top-notch, polished user experience for your app
- Futue-proof the code in your app, to minimize work as new versions of iOS come out
- Launch quickly when the app first lanches
- That's how you make your app appear quick, performant
- How to: return quikcly from
applicationDidFinishLaunching:
- Do this by deferring long running work
- Users will kill your app if it's too slow, because they think it's unreponsinve
- Be responsive to every input
- Not just about asynchrony
- Move long running work to background queues
- This can be applied any time in your app, not just at launch
- Once work is done, perform UI updates on the main queue
- Launch quickly when the app is opened again
- If your app is using a lot of memory when it's in the background, it's the first one to get killed
- When your app is background-ed, get rid of unused resources/memory.
- Leverage apple's frameworks
- Reduces maintenance burden. I.e, use
UINavigationController
instead of rolling your own - You get improvements for free
- You're able to focus time on whatever makes your app special
- Reduces maintenance burden. I.e, use
- Properly manage version change
- Target the 2 most recent major releases (i.e iOS 8 and 9, as of this fall)
- Include version fallbacks.
- DO NOT DO THIS:
if systemVersion == 9.0
- DO THIS INSTEAD:
if systemVersion >= 9.0
(this is future proofing?! meh.) - OR DO THIS:
#available(iOS 9.0, *) {}
(new in swift.) - have an else clause
- Layout on modern devices: layout to proportions
- Avoid hard-coded layout values
- Either (or both!) dimissions may scale
- ex: Instead of thinking of a view containing a label that's 260 pixels wide with 30, think of it as a view that contains a centered label
- Don't think about things in terms of portrait/landscape
- Think about them interms of size classes instead
- Make your designers think about it in terms of size classes also.
- Packaged in
UITraitCollection
- Use properties, not tags
- If you need a reference to a subview, save it as a property (instead of refefrring it to by tag)
- Avoid
setTag:
andviewWithTag:
- Possible collisions with other code
- No compiler warnings
- No runtime errors - best case is a crash
- Instead, use instance variables and properties
- Make timing deterministic
- Don't "guess" how long an animation will take.
- Leverage
UIViewControllerTransitionCoordinator
- Animate alongisde a transition
- Get accurate completion timing
- Supports interactive and cancellable animations (!)
- Modify constraints efficiently
- Identify constraints that get changed, add or removed.
- Unchanged constraints are optimized
- Avoid removing all constraints. (Removing all constraitns is worst practice, the opposite of best practice)
- Use explict constraint references (via properties)
- Same as the advice about tags.
- Don't add duplicate constraints.
- Duplicates are implied by existing cosntraints
- Can cause excess work for the layout engine
- Create flexible constraints
- Avoid hard-code values (eg:
V:-30-[label(260)]
) is bad.- Missed the good counter-example
- Avoid hard-code values (eg:
- Fully specify constraints
- Underspecified constraints generate ambiguiity
- Ambiguity can cause undefined, non-deterministc behaviro
- Testing and debugging:
-[UIView.hasAmbiguousLayout]
- tells whether a view has ambigusous layout. Can also be called on UIWindow to get results for the entire view tree-[UIView _autolayoutTrace]
- Put both these methods in your unit tests. Test whether a view has ambivuous layout. If it does, run the
_autolayoutTrace
method to include the layout in your logs
- Use self-sizing cells. (Introduced in iOS 8)
- Fully specify the constraints for your cell
- Think about it as a machine that has width as its input and returns height as its output
- If it's not working, try setting a constraint on the height of your content view. You can use this as a debugging tactic - if it fixes your problem, your constriants are wrong
- Fully specify the constraints for your cell
- Animating tableview cell height changes
- Don't call reload data. Looks jenkity.
- You want nearby cells to also animate their position changes
- You don't need to call
reloadCellsAtIndexPaths
- you can just change the content directly.
tableview.beginUpdates Update model Update cell contents tableView.endUpdates
- Fast collection view layout invalidation
- Modify only what is needed
- Invalidate on bounds change
- Build targeted invalidation context
- Repeate as ncessary
- This is a fast technique. (This is what the iPhone photos app uses for its sticky header)
- Modify only what is needed