kkbox wwdc17 uikit - qq

Post on 22-Jan-2018

2.099 Views

Category:

Technology

9 Downloads

Preview:

Click to see full reader

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

top related