kkbox wwdc17 uikit - qq
TRANSCRIPT
WWDC17 讀書會
QQ Shih
UIKit
2017/07/07
• What’s new in Cocoa Touch
• The keys to a better text input experience
• Introducing password autofill for apps
• Building apps with dynamic type
• Updating your app for iOS 11
• Advanced animations with UIKit
What’s new in Cocoa Touch
•Drag and Drop
Drag and Drop Enabling drags
let drag = UIDragInteraction(delegate: self) iconView.addInteraction(drag)
UIDragInteractionDelegate • Provide data for dragged item • Customize lift animation • Customize preview
Drag and Drop Enabling drops
let drop = UIDropInteraction(delegate: self) iconContainerView.addInteraction(drop)
UIDropInteractionDelegate • Update UI as drag moves • Receive data on drop • Customize drop animation
Drag and Drop Easy to adopt
Introducing Drag and Drop Hall 3 Tuesday 11:20AM
Mastering Drag and Drop Executive Ballroom Wednesday 11:00AM
Drag and Drop with Collection and Table View Hall 2 Thursday 9:00AM
Data Delivery with Drag and Drop Hall 2 Thursday 10:00AM
Built-in support • TableView, CollectionView, TextView, TextField, WebView
Integration with UIPasteConfiguration
File management
Highly customizable
Access to local documents and cloud storage
Be sure to coordinate file access• NSFileCoordinator or UIDocument
File Management UIDocumentBrowserViewController
Building Great Document-Based Apps in iOS 11 Hall 2 Thursday 1:50PM
class UIDocumentBrowserViewController { init(forOpeningFilesWithContentTypes: [String]?) var delegate: UIDocumentBrowserViewControllerDelegate?
}
class UINavigationBar { var prefersLargeTitle: Bool
}
Enabling Large Titles
class UINavigationItem { var largeTitleDisplayMode: LargeTitleDisplayMode
}
Enabling Unified Search
class UINavigationItem { var searchController: UISearchController?
}
Safe Area Insets
class UIView {
// auto layout var safeAreaLayoutGuide: UILayoutGuide { get }
// manual layout var safeAreaInsets: UIEdgeInsets { get }
func safeAreaInsetsDidChange()
}
class UIViewController { func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge
}
Asset Catalogs Colors and icons
class UIColor { init?(named name: String)
}
Wide gamut color support
Wide gamut colors for icons
App thinning for icons
Asset Catalogs PDF-backed images
Preserve vector data if• Image used at multiple sizes• Symbolic glyph that resizes with dynamic type• Tab bar image
Localization Guide https://developer.apple.com/internationalization
The keys to a better text input experiece
Text Input Context Identifier
class ConversationViewController: UITableViewController, UITextViewDelegate {
// ... other code ...
override var textInputContextIdentifier: String? {
// Returning some unique identifier here allows the keyboard to remember
// which language the user was typing in when they were last communicating
// with this person.
// It can be anything, as long as it's unique to each
// recipient (here we're just returning the name)
return self.conversation?.otherParticipant
}
// ... other code ...
}
Multilingual
Content Types for Password AutoFill
Introducing Password AutoFill for Apps WWDC 2017
NEW
Log In
UITextContentTypeUsername
UITextContentTypePassword
Smart Quote and Smart Dash
Hyphen: 1-dash - ➜ -
En dash: 2-dash - - ➜ –
Em dash: 3-dash - - - ➜ —
SF Hello "a" “a”
Helvetica Neue "a" “a”
Lucida Grande "a" “a”Avenir "a" “a”
Myriad Set "a" “a”
NEW
New APIs in iOS 11
Selected text
documentIdentifier handle
Ability to query for full access
NEW
Full Access and Privacy
Value in not asking for full access
Communicating with your main app
Networking
Current location
Address book
Keyboard needs to work without it
Introducing password autofill for apps
Make the QuickType Bar Appear Use UITextContentType
Deploy content types to guarantee AutoFill is available
Can set in code or through Interface Builder
UITextContentType.username enables AutoFill for two-screen login
You can combine UITextContentType.username and UIKeyboardType.emailAddress
UITextContentType.password enables AutoFill for “revealed” passwords
Associated Domains File Where to serve the file
https://example.com/.well-known/apple-app-site-association
https://example.com/apple-app-site-association
Building app with dynamic type
Goals
Text is large enough for the user to read
Text is fully readable
App UI looks beautiful
Design For Everyone WWDC 2017
•Scaling Font Sizes
Text Styles
Standard Sizes Accessibility Sizes
NEW
Text Styles NEW
Custom Fonts
label.font = UIFontMetrics.default.scaledFont(for: customFont)
NEW
•Accommodating Large Text
.extraSmall .extraExtraExtraLarge
.large
traitCollection.preferredContentSizeCategoryUIApplication.shared.preferredContentSizeCategory
Make Layout Decisions Based on Text Size
if traitCollection.preferredContentSizeCategory.isAccessibilityCategory { // Vertically stack } else { // Lay out side by side }
NEW
Make Layout Decisions Based on Text Size
if traitCollection.preferredContentSizeCategory > .extraExtraLarge { // Vertically stack } else { // Lay out side by side }
NEW
Default Table View Behaviors in iOS 11
Standard table view cells adapt layout for Dynamic Type
Cell heights are based on their content
NEW
•Images
Allow Images to Scale Up
Provide PDF at 1x scale
NEW
Allow Images to Scale UpNEW
Allow Bar Item Images to Scale SmoothlyNEW
Updating your app for iOS 11
UIBarItem
UIBarItem.landscapeImagePhoneUIBarItem.largeContentSizeImage
Manage margin and insets
NEW
Here’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
TitlelayoutMargins
directionalLayoutMargins
NEW
Here’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
Title
.trailing
.left
.leading
.right
NEW
Here’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
Title
.trailing = 30
NEW
Here’s to the crazy ones. The misfits. The rebels. The
troublemakers. The round pegs in the square holes. The ones who see
things differently. They’re not fond of rules. And they have no respect
for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you
can’t do is ignore them. Because they change things. They push the
human race forward. And while some may see them as the crazy
ones, we see genius. Because the people who are crazy enough to
think they can change the world, are the ones who do.
כותרת
.left = 30
.trailing = 30
NEW
Here’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the
Title
systemMinimumLayoutMargins
directionalLayoutMargins
class MyViewController: UIViewController { override func viewDidLoad() { viewRespectsSystemMinimumLayoutMargins = true // default
} }
safeAreaInsets.bottom
safeAreaInsets.top
Safe Area
Describes area of view not occludedby ancestors
Available as insets or layout guide
Incorporates overscan compensation insets
NEW
UIView.safeAreaInsets
Safe Area
Describes area of view not occludedby ancestors
Available as insets or layout guide
Incorporates overscan compensation insets
NEW
UIView.safeAreaLayoutGuide
Safe Area
Describes area of view not occludedby ancestors
Available as insets or layout guide
Incorporates overscan compensation insets
NEW
UIScreen.overscanCompensationInsets
Extending the Safe Area Insets
UIViewController.additionalSafeAreaInsets UIView.safeAreaInsetsDidChange() UIViewController.viewSafeAreaInsetsDidChange()
NEW
TitleHere’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
NEW
101 words • Modified today
adjustedContentInset.topcontentInset.top
Safe Area Insets
class UIScrollView {
var contentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentBehavior
var adjustedContentInset: UIEdgeInsets { get }
}
101 words • Modified today
NEWTitleHere’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
contentLayoutGuidePage 1
frameLayoutGuide
Self-Sizing by Default
Link on iOS 11, all estimated heights default to UITableViewAutomaticDimension
Headers, footers, and cells use self-sizing by default
iOS only—behavior is not changed on tvOS
Ensure all views have sufficient internal constraints
Return fixed sizes from delegate methods
NEW
Opting Out of New Behavior
Set table view estimated height properties to zero
Also disables self-sizing
override func viewDidLoad() { tableView.estimatedRowHeight = 0 tableView.estimatedSectionHeaderHeight = 0 tableView.estimatedSectionFooterHeight = 0 }
NEW
separatorInset.left = 60
class MyViewController: UITableViewController { override func viewDidLoad() { tableView.separatorInsetReference = .fromCellEdges // default
} }
Table view cell
NEW
separatorInset.left = 60
class MyViewController: UITableViewController { override func viewDidLoad() { tableView.separatorInsetReference = .fromAutomaticInsets
} }
Table view cell
NEW
Swipe Actions
New look-and-feel automatically for all table views
Supports full swipe-to-delete for iOS 11-linked apps
New features with API adoption • Images • Leading and trailing actions • Completion handler and cancellation
NEW
Advanced Animations With UIKit
UIViewPropertyAnimator Features
Custom timing
Interactive
Interruptible
Responsive
UIViewPropertyAnimator
let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()
0 100x
Progress 1.0
0.0 1.0
0.5
0.5 Time
Ease In Ease Out
.easeIn
1.0
0.0 1.0
0.5
0.5
.easeOut
Timing Curves
UICubicTimingParameters(controlPoint1: CGPoint(x: 0.75, y: 0.1), controlPoint2: CGPoint(x: 0.9, y: 0.25))
(0.75, 0.1)
(0.9, 0.25)
Custom Curves
Progress
Custom Ease In
1.0
0.0 1.0
0.5
0.5 Time
•Interactively Animating
var animator: UIViewPropertyAnimator!
func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }
1.0
0.0 1.0
0.5
0.5
animator.fractionComplete = translation.x / distance
Progress
Time
1.0
0.0 1.0
0.5
0.5
animator.fractionComplete = translation.x / distance
Progress
Time
1.0
0.0 1.0
0.5
0.5
Progress
Time
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
running true
fractionComplete 10%
animationState .active
•New Animator Behaviors
UIViewPropertyAnimator New in iOS 11
var scrubsLinearly: Bool var pausesOnCompletion: Bool
NEW
.Inactive
Animations finish
.pausesOnCompletion
.Active
Start / pause
animator.addObserver(self, forKeyPath: "running", options: [.new], context: nil)
Starting as Paused
let animator = UIViewPropertyAnimator(duration: 1, curve: .easeIn) animator.startAnimation() // ... animator.addAnimations { // will run immediately circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }
No escaping for animation blocks
NEW
.cornerRadius Now animatable in UIKit
CALayer var .cornerRadius: CGFloat
circle.clipsToBounds = true UIViewPropertyAnimator(duration: 1, curve: .linear) { circle.layer.cornerRadius = 12 }.startAnimation()
NEW
.maskedCorners New in iOS 11
CALayer var .maskedCorners: CACornerMask
circle.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
NEW
Thank You