Mastering UIKit on tvos

Similar documents
Advanced Scrollviews and Touch Handling Techniques

Enhancing your apps for the next dimension of touch

Leveraging Touch Input on ios

Modern User Interaction on ios

Implementing UI Designs in Interface Builder

Mastering Drag and Drop

New UIKit Support for International User Interfaces

Quick Interaction Techniques for watchos

What s New in tvos #WWDC16. App Frameworks. Session 206. Hans Kim tvos Engineer

Building Watch Apps #WWDC15. Featured. Session 108. Neil Desai watchos Engineer

Event Delivery: The Responder Chain

Extending Your Apps with SiriKit

What s New in tvos 12

Monetize and Promote Your App with iad

What s New in watchos

Using and Extending the Xcode Source Editor

Data Delivery with Drag and Drop

Media and Gaming Accessibility

What s New in Xcode App Signing

Accessibility on ios. Developing for everyone. Frameworks #WWDC14. Session 210 Clare Kasemset ios Accessibility

What s New in imessage Apps

imessage Apps and Stickers, Part 2

Introducing Password AutoFill for Apps

Mysteries of Auto Layout, Part 1

lecture 10 UI/UX and Programmatic Design cs : spring 2018

What s New in SpriteKit

Cocoa Touch Best Practices

View Controller Advancements for ios8

What's New in UIKit Dynamics and Visual Effects Session 229

Introducing the Modern WebKit API

Managing Documents In Your ios Apps

Lecture 8 Demo Code: Cassini Multithreading

WatchKit In-Depth, Part 2

Building Apps with Dynamic Type

ios Accessibility Developing for everyone Session 201 Ian Fisch ios Accessibility

Introduction to Siri Shortcuts

Advanced Notifications

App Extension Best Practices

Designing Great Apple Watch Experiences

Touch Bar Fundamentals

CarPlay Audio and Navigation Apps

Improving your Existing Apps with Swift

Designing for Apple Watch

Creating Content with iad JS

Apple Watch Design Tips and Tricks

Seamless Linking to Your App

Announcements. Today s Topics

Enabling Your App for CarPlay

Automatic Strong Passwords and Security Code AutoFill

Introducing Swift Playgrounds

What s New in MapKit. App Frameworks #WWDC17. Fredrik Olsson

What s New in NSCollectionView Session 225

Building Faster in Xcode

Accessibility on OS X

Getting the Most Out of HealthKit

Thread Sanitizer and Static Analysis

CSC 581: Mobile App Development Spring 2018

Advances in AVFoundation Playback

What s New in SiriKit

Using the Microsoft Remote Desktop on non-windows devices

Building Visually Rich User Experiences

Creating Complications with ClockKit Session 209

EXERCISES RELATED TO ios PROGRAMMING

Building for Voice with Siri Shortcuts

Writing Energy Efficient Apps

Creating Great App Previews

Mobile Application Programing: ios. Messaging

ITP 342 Mobile App Dev. Collection View

Announcements. Today s Topics

Lifespan Guide for installing and using Citrix Receiver on your Mobile Device

App. Chapter 19 App. App (ViewController) App. Single View Application Single View Application View. (View Controller)

What s New in Testing

Adopting Advanced Features of the New UI

ios Configuration and APIs for Kiosk and Assessment Apps

Mastering Xcode for iphone OS Development Part 2. Marc Verstaen Sr. Manager, iphone Tools

Introducing On Demand Resources

HKUST. CSIT 6910A Report. iband - Musical Instrument App on Mobile Devices. Student: QIAN Li. Supervisor: Prof. David Rossiter

ITP 342 Mobile App Dev. Connections

Core ML in Depth. System Frameworks #WWDC17. Krishna Sridhar, Core ML Zach Nation, Core ML

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

Social Pinboard: ios(swift) Application

Adapting to the New UI of OS X Yosemite

Introducing SiriKit. Hey Siri, say hello to apps #WWDC16. App Frameworks. Session 217

Localizing with Xcode 9

Mobile Development - Lab 2

Introducing the Photos Frameworks

Introductory ios Development

Advances in TVMLKit. App Frameworks #WWDC17. Trevor Cortez, Localization Engineer Parry Panesar, tvos Engineer Jeremy Foo, tvos Engineer

What s New in ARKit 2

New Ways to Work with Workouts

ios Application Development Lecture 5: Protocols, Extensions,TabBar an Scroll Views

Using Grouped Notifications

Mobile Application Programming. Controls

Advanced Debugging and the Address Sanitizer

Optimizing Swift Performance Session 409

Integrating Apps and Content with AR Quick Look

Stanford CS193p. Developing Applications for ios. Fall CS193p. Fall

JVC Remote Application

Creating Audio Apps for watchos

Gestures. Mobile Application Development in ios School of EECS Washington State University Instructor: Larry Holder

Transcription:

App Frameworks #WWDC16 Mastering UIKit on tvos Session 210 Justin Voss UIKit Engineer 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Agenda

Agenda Event Handling

Agenda Event Handling Layered Images

Agenda Event Handling Layered Images Scrolling

Agenda Event Handling Layered Images Scrolling Text Input

Event Handling

Event Handling Best Practices

Event Handling Best Practices Navigation should rely on the focus engine

Event Handling Best Practices Navigation should rely on the focus engine Use gesture recognizers when possible

Event Handling Best Practices Navigation should rely on the focus engine Use gesture recognizers when possible Avoid gestures that can t be used on all input devices

Touches

Touches UITouch represents contact between the user s finger and the touch surface

Touches UITouch represents contact between the user s finger and the touch surface Just like the ios version

Touches UITouch represents contact between the user s finger and the touch surface Just like the ios version UITouchTypeIndirect

Touches UITouch represents contact between the user s finger and the touch surface Just like the ios version UITouchTypeIndirect Begins centered in the focused view

Touches UITouch represents contact between the user s finger and the touch surface Just like the ios version UITouchTypeIndirect Begins centered in the focused view No absolute coordinates on the touch surface

Presses

Presses UIPress represents the up or down state of a physical button

Presses UIPress represents the up or down state of a physical button May be pressure-sensitive

Presses UIPress represents the up or down state of a physical button May be pressure-sensitive UIGestureRecognizer

Presses UIPress represents the up or down state of a physical button May be pressure-sensitive UIGestureRecognizer UIPress events mimic UITouch events

Presses UIPress represents the up or down state of a physical button May be pressure-sensitive UIGestureRecognizer UIPress events mimic UITouch events func pressesbegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {} func presseschanged(_ presses: Set<UIPress>, with event: UIPressesEvent?) {} func pressesended(_ presses: Set<UIPress>, with event: UIPressesEvent?) {} func pressescancelled(_ presses: Set<UIPress>, with event: UIPressesEvent?) {}

Press Types An illustrated guide

Press Types An illustrated guide

Press Types An illustrated guide

Press Types An illustrated guide

Press Types UIPressTypeSelect An illustrated guide

Press Types UIPressTypeSelect An illustrated guide

Press Types UIPressTypeSelect An illustrated guide

Press Types UIPressTypeSelect An illustrated guide

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu UIPressTypePlayPause

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu UIPressTypePlayPause

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu UIPressTypePlayPause

Press Types An illustrated guide UIPressTypeSelect UIPressTypeMenu UIPressTypePlayPause

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

Press Types An illustrated guide UIPressTypeUpArrow UIPressTypeDownArrow UIPressTypeLeftArrow UIPressTypeRightArrow

// Tap on Play-Pause button. let playpausetap = UITapGestureRecognizer(target: self, action: #selector(myclass.handleplaypause(_:))) playpausetap.allowedpresstypes = [ UIPressType.playPause.rawValue ] // Long-press on Select button. let selectlongpress = UILongPressGestureRecognizer(target: self, action: #selector(myclass.handleselectlongpress(_:))) selectlongpress.allowedpresstypes = [ UIPressType.select.rawValue ] // Double-tap on Select button. let selectdoubletap = UITapGestureRecognizer(target: self, action: #selector(myclass.handleselectdoubletap(_:))) selectdoubletap.allowedpresstypes = [ UIPressType.select.rawValue ] selectdoubletap.numberoftapsrequired = 2

The Menu Button

The Menu Button Users must be able to exit your app using the Menu button

The Menu Button Users must be able to exit your app using the Menu button This is a requirement that App Review specifically looks for

The Menu Button Users must be able to exit your app using the Menu button This is a requirement that App Review specifically looks for The event must reach UIApplication pressesended:withevent: in order for the app to exit

Custom Menu Button Handling

Custom Menu Button Handling Remove the gesture from its view

Custom Menu Button Handling Remove the gesture from its view Disable the gesture

Custom Menu Button Handling Remove the gesture from its view Disable the gesture Implement the gesture delegate method gesturerecognizershouldbegin

Custom Menu Button Handling Remove the gesture from its view Disable the gesture Implement the gesture delegate method gesturerecognizershouldbegin In pressesended call super if you re not going to handle the event

Custom Menu Button Handling Remove the gesture from its view Disable the gesture Implement the gesture delegate method gesturerecognizershouldbegin In pressesended call super if you re not going to handle the event GCEventViewController and controlleruserinteractionenabled

Layered Images

Layered Images

Layered Images

Layered Images Specific to tvos

Layered Images Specific to tvos Can have up to five layers

Layered Images Specific to tvos Can have up to five layers Required for app icons

Layered Images Specific to tvos Can have up to five layers Required for app icons Interactive

Layered Images Specific to tvos Can have up to five layers Required for app icons Interactive Animated

Interactivity with Layered Images

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true The image view can show a pressed-in state

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true The image view can show a pressed-in state imageview.ishighlighted = pressed? true : false

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true The image view can show a pressed-in state imageview.ishighlighted = pressed? true : false Two common use cases that are covered for you:

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true The image view can show a pressed-in state imageview.ishighlighted = pressed? true : false Two common use cases that are covered for you: Images inside UICollectionViewCells

Interactivity with Layered Images Images are usually not interactive controls themselves, but components of larger controls The image view itself doesn t need to be focused to get the floating appearance imageview.adjustsimagewhenancestorfocused = true The image view can show a pressed-in state imageview.ishighlighted = pressed? true : false Two common use cases that are covered for you: Images inside UICollectionViewCells The imageview within a custom UIButton

Animations with Layered Images

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint

Animations with Layered Images When an image enlarges, you can rearrange nearby views using Auto Layout Use the layout guide focusedframeguide to create a constraint Use focus context methods to coordinate animations correctly

Demo Interactivity and animation for layered images Randy Becker

Scrolling

Scroll Offset Selection

Scroll Offset Selection Usually not doing direct manipulation

Scroll Offset Selection Usually not doing direct manipulation The user manipulates focus, and the focus engine chooses a scroll offset

Scroll Offset Selection Usually not doing direct manipulation The user manipulates focus, and the focus engine chooses a scroll offset UIScrollViewDelegate can override the automatic scroll offset

Scroll Offset Selection Usually not doing direct manipulation The user manipulates focus, and the focus engine chooses a scroll offset UIScrollViewDelegate can override the automatic scroll offset func scrollviewwillenddragging(_ scrollview: UIScrollView, withvelocity velocity: CGPoint, targetcontentoffset: UnsafeMutablePointer<CGPoint>) { let myoffset = CGPoint(x: 42.0, y: 0) // Do your own calculations here. targetcontentoffset.initialize(with: myoffset) }

Direct Manipulation

Direct Manipulation It is possible to do direct manipulation if the situation calls for it

Direct Manipulation It is possible to do direct manipulation if the situation calls for it Reconfigure pan gesture recognizer on scroll view to recognize indirect touches

Direct Manipulation It is possible to do direct manipulation if the situation calls for it Reconfigure pan gesture recognizer on scroll view to recognize indirect touches Enable the directional press gesture

Direct Manipulation It is possible to do direct manipulation if the situation calls for it Reconfigure pan gesture recognizer on scroll view to recognize indirect touches Enable the directional press gesture scrollview.pangesturerecognizer.allowedtouchtypes = [ UITouchType.indirect.rawValue ] scrollview.directionalpressgesturerecognizer.isenabled = true

Demo Focus and direction manipulation Kevin Hiscott

Text Input

The System Keyboard

The System Keyboard The system standard keyboard is the only way to get certain text input features

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation Bluetooth keyboards

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation Bluetooth keyboards Apple TV Remote app

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation Bluetooth keyboards Apple TV Remote app Localization

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation Bluetooth keyboards Apple TV Remote app Localization Automatic grid or linear layout based on input device

The System Keyboard The system standard keyboard is the only way to get certain text input features Dictation Bluetooth keyboards Apple TV Remote app Localization Automatic grid or linear layout based on input device Don t try to create your own keyboard, or your users will miss out on these features

Keyboard Appearance

Keyboard Appearance Adding custom UI to the keyboard is possible

Keyboard Appearance Adding custom UI to the keyboard is possible Use inputaccessoryview or inputaccessoryviewcontroller

Keyboard Appearance Adding custom UI to the keyboard is possible Use inputaccessoryview or inputaccessoryviewcontroller UITextField appearance no longer dictated by keyboardappearance

Search Controller

Search Controller UISearchController

Search Controller UISearchController Keyboard and search results visible at the same time

Search Controller UISearchController Keyboard and search results visible at the same time Automatically adapts to linear and grid keyboards

Search Controller UISearchController Keyboard and search results visible at the same time Automatically adapts to linear and grid keyboards Can be embedded within container view controllers

Search Controller UISearchController Keyboard and search results visible at the same time Automatically adapts to linear and grid keyboards Can be embedded within container view controllers UISearchContainerViewController

Search Controller UISearchController Keyboard and search results visible at the same time Automatically adapts to linear and grid keyboards Can be embedded within container view controllers UISearchContainerViewController Custom view controller for search results

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

// Embedding UISearchController class MySearchController: UIViewController, UISearchResultsUpdating { var searchcontroller: UISearchController! override func viewdidappear(_ animated: Bool) { super.viewdidappear(animated) if (searchcontroller == nil) { let results = UIViewController() searchcontroller = UISearchController(searchResultsController: results) searchcontroller.searchresultsupdater = self let container = UISearchContainerViewController (searchcontroller: searchcontroller) self.addchildviewcontroller(container) self.view.addsubview(container.view) container.didmove(toparentviewcontroller: self) } } }

Summary

Summary Be careful with custom Menu button handling

Summary Be careful with custom Menu button handling Use layout guides and coordinated animations for great layered images

Summary Be careful with custom Menu button handling Use layout guides and coordinated animations for great layered images If you need direct manipulation, use the existing UIScrollView gestures

Summary Be careful with custom Menu button handling Use layout guides and coordinated animations for great layered images If you need direct manipulation, use the existing UIScrollView gestures Use the system standard keyboard for text input

More Information developer.apple.com/wwdc16/210

Related Sessions What s New in tvos Presidio Tuesday 3:00PM Focus Interaction on tvos Mission Wednesday 4:00PM

Labs tvos Lab Frameworks Lab D Wednesday 2:00PM tvos Lab Frameworks Lab D Thursday 9:00AM