Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
23 views190 pages

240 Swiftui On All Devices

The document discusses SwiftUI, a framework designed for building apps across multiple Apple platforms including iOS, macOS, tvOS, and watchOS. It emphasizes the importance of leveraging platform strengths while sharing code and skills, and introduces a sample app called 'Landmarks' that showcases various functionalities on different devices. The presentation highlights the unique navigation and user experience considerations for each platform, particularly focusing on the 10-foot experience for tvOS.

Uploaded by

happyhan2003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views190 pages

240 Swiftui On All Devices

The document discusses SwiftUI, a framework designed for building apps across multiple Apple platforms including iOS, macOS, tvOS, and watchOS. It emphasizes the importance of leveraging platform strengths while sharing code and skills, and introduces a sample app called 'Landmarks' that showcases various functionalities on different devices. The presentation highlights the unique navigation and user experience considerations for each platform, particularly focusing on the 10-foot experience for tvOS.

Uploaded by

happyhan2003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 190

#WWDC19

SwiftUI On All Devices

Jeff Nadeau, macOS Frameworks


Ada Turner, tvOS Frameworks
Meghna Sapre, watchOS Frameworks

© 2019 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
The shortest path to building great
apps on every device
The shortest path to building great
apps on every device
The shortest path to building great
apps on every device
AppKit UIKit TVUIKit WatchKit
UIKit
AppKit UIKit TVUIKit WatchKit
UIKit
AppKit UIKit TVUIKit WatchKit
UIKit
Designed for Every Platform

Designed to accommodate many UI paradigms

Platform support out of the box

A common toolkit that you can learn once and use anywhere
Common Elements
Basic controls

iOS Bluetooth

macOS Bluetooth

tvOS Bluetooth On

watchOS Bluetooth
Common Elements
Basic controls

Toggle(isOn: $btEnabled) {
Text("Bluetooth")
} iOS Bluetooth

macOS Bluetooth

tvOS Bluetooth On

watchOS Bluetooth
Common Elements
Layout

HStack {
Text("Label")

Spacer()

Button(action: /* */) {
Label Delete Cancel
Text("Delete")
}

Button(action: /* */) {
Text("Cancel")
}
}
.padding()
Common Elements
Advanced controls

Picker(selection: /* */, label: /* */) { macOS


ForEach(allFruits) { fruit in
Text(verbatim: fruit.name)
}
} iOS

watchOS
Common Elements
Advanced controls

Picker(selection: /* */, label: /* */) { macOS


ForEach(allFruits) { fruit in
Text(verbatim: fruit.name)
}
} iOS

watchOS

SwiftUI Essentials WWDC 2019


Of course not
One Size Does Not Fit All
One Size Does Not Fit All

There’s no such thing as a “one size fits all app”


One Size Does Not Fit All

There’s no such thing as a “one size fits all app”

Make the most of each platform’s strengths


One Size Does Not Fit All

There’s no such thing as a “one size fits all app”

Make the most of each platform’s strengths

Share skillset and toolset


One Size Does Not Fit All

There’s no such thing as a “one size fits all app”

Make the most of each platform’s strengths

Share skillset and toolset

Share code where it makes sense


Write once, run anywhere
Write once, run anywhere
Learn once, apply anywhere
Learn once, apply anywhere
We built an app
We built four apps
Landmarks
Landmarks

Research and visit landmarks


Landmarks

Research and visit landmarks

Look at photos and visitor info


Landmarks

Research and visit landmarks

Look at photos and visitor info

Get maps and directions


Landmarks

Research and visit landmarks

Look at photos and visitor info

Get maps and directions

Mark favorites
Landmarks for Apple TV
Landmarks for Apple TV

Couch surfing for places to go


Landmarks for Apple TV

Couch surfing for places to go

Together with family or friends


Landmarks for Apple TV

Couch surfing for places to go

Together with family or friends

Mark favorites to research later


Landmarks for Mac
Landmarks for Mac

Research many options in detail


Landmarks for Mac

Research many options in detail

Compare information
Landmarks for Mac

Research many options in detail

Compare information

Sort and filter


Landmarks for Mac

Research many options in detail

Compare information

Sort and filter

Read up on the details


Landmarks for iOS
Landmarks for iOS

Quick information about each landmark


Landmarks for iOS

Quick information about each landmark

Get driving directions


Landmarks for iOS

Quick information about each landmark

Get driving directions

Place a phone call


Landmarks for Apple Watch
Landmarks for Apple Watch

Get at-a-glance info about the current location


Landmarks for Apple Watch

Get at-a-glance info about the current location

Receive important notifications


Learning Experience
Learning Experience

New documentation series


Learning Experience

New documentation series

Build the app step-by-step


Learning Experience

New documentation series

Build the app step-by-step

Available for download today


SwiftUI on Apple TV

Ada Turner, tvOS Frameworks


The biggest, boldest screen
The Biggest, Boldest Screen
The Biggest, Boldest Screen

10-foot experience
The Biggest, Boldest Screen

10-foot experience

Focus and the Siri Remote


The Biggest, Boldest Screen

10-foot experience

Focus and the Siri Remote

Streamlined navigation
What is a 10-foot experience?
10-Foot Experience
10-Foot Experience

Large screen
10-Foot Experience

Large screen

Long viewing distance


10-Foot Experience

Large screen

Long viewing distance

Extended periods of use


10-Foot Experience

Large screen

Long viewing distance

Extended periods of use

Multiple viewers at the same time


Landmarks — What Makes the Cut?
Landmarks — What Makes the Cut?

Beautiful photos of landmarks


Landmarks — What Makes the Cut?

Beautiful photos of landmarks

Adding favorites
Landmarks — What Makes the Cut?

Beautiful photos of landmarks

Adding favorites

Basic tourism information


Landmarks — What Makes the Cut?

Beautiful photos of landmarks Lengthy historical information

Adding favorites

Basic tourism information


Landmarks — What Makes the Cut?

Beautiful photos of landmarks Lengthy historical information

Adding favorites Advanced sorting and filtering

Basic tourism information


Landmarks — What Makes the Cut?

Beautiful photos of landmarks Lengthy historical information

Adding favorites Advanced sorting and filtering

Basic tourism information Location-based notifications


Focus and the Siri Remote
Focus and the Siri Remote
Focus and the Siri Remote

Entire interface must support focus


Focus and the Siri Remote

Entire interface must support focus

SwiftUI supports focus by default


// Custom Focusable Views

struct MyFocusableView: View {


let canBecomeFocused: Bool
var body: some View {
return Text("Hello WWDC")
.focusable(canBecomeFocused) { isFocused in
// Focus changed
}
.onPlayPauseCommand {
// Play/pause button pressed
}
.onExitCommand {
// Menu button pressed
}
}
}
// Custom Focusable Views

struct MyFocusableView: View {


let canBecomeFocused: Bool
var body: some View {
return Text("Hello WWDC")
.focusable(canBecomeFocused) { isFocused in
// Focus changed
}
.onPlayPauseCommand {
// Play/pause button pressed
}
.onExitCommand {
// Menu button pressed
}
}
}
// Custom Focusable Views

struct MyFocusableView: View {


let canBecomeFocused: Bool
var body: some View {
return Text("Hello WWDC")
.focusable(canBecomeFocused) { isFocused in
// Focus changed
}
.onPlayPauseCommand {
// Play/pause button pressed
}
.onExitCommand {
// Menu button pressed
}
}
}
// Custom Focusable Views

struct MyFocusableView: View {


let canBecomeFocused: Bool
var body: some View {
return Text("Hello WWDC")
.focusable(canBecomeFocused) { isFocused in
// Focus changed
}
.onPlayPauseCommand {
// Play/pause button pressed
}
.onExitCommand {
// Menu button pressed
}
}
}
Streamlined navigation
// TabbedView and NavigationView on tvOS

struct MainView: View {


enum Tab { case explore, hikes, tours }
@State var selection: Tab
var body: some View {
return NavigationView {
TabbedView(selection: $selection) {
ExploreView().tabItemLabel(Text("Explore")).tag(Tab.explore)
HikesView().tabItemLabel(Text("Hikes")).tag(Tab.hikes)
ToursView().tabItemLabel(Text("Tours")).tag(Tab.tours)
}
}
}
}
// TabbedView and NavigationView on tvOS

struct MainView: View {


enum Tab { case explore, hikes, tours }
@State var selection: Tab
var body: some View {
return NavigationView {
TabbedView(selection: $selection) {
ExploreView().tabItemLabel(Text("Explore")).tag(Tab.explore)
HikesView().tabItemLabel(Text("Hikes")).tag(Tab.hikes)
ToursView().tabItemLabel(Text("Tours")).tag(Tab.tours)
}
}
}
}
// TabbedView and NavigationView on tvOS

struct MainView: View {


enum Tab { case explore, hikes, tours }
@State var selection: Tab
var body: some View {
return NavigationView {
TabbedView(selection: $selection) {
ExploreView().tabItemLabel(Text("Explore")).tag(Tab.explore)
HikesView().tabItemLabel(Text("Hikes")).tag(Tab.hikes)
ToursView().tabItemLabel(Text("Tours")).tag(Tab.tours)
}
}
}
}
// TabbedView and NavigationView on tvOS

struct MainView: View {


enum Tab { case explore, hikes, tours }
@State var selection: Tab
var body: some View {
return NavigationView {
TabbedView(selection: $selection) {
ExploreView().tabItemLabel(Text("Explore")).tag(Tab.explore)
HikesView().tabItemLabel(Text("Hikes")).tag(Tab.hikes)
ToursView().tabItemLabel(Text("Tours")).tag(Tab.tours)
}
}
}
}
tvOS vs. iOS Navigation Hierarchies
tvOS vs. iOS Navigation Hierarchies

iOS

TabbedView
tvOS vs. iOS Navigation Hierarchies

iOS

TabbedView

NavigationView Content NavigationView


tvOS vs. iOS Navigation Hierarchies

iOS

TabbedView

NavigationView Content NavigationView

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS

TabbedView

NavigationView Content NavigationView

Content Content

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS

TabbedView

NavigationView Content NavigationView

Content Content

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView NavigationView

NavigationView Content NavigationView

Content Content

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView NavigationView

NavigationView Content NavigationView TabbedView

Content Content

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView NavigationView

NavigationView Content NavigationView TabbedView

Content Content Content Content Content

Content Content
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView NavigationView

NavigationView Content NavigationView TabbedView

Content Content Content Content Content

Content Content Content Content Content


tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView(selection: $selection) { NavigationView {


NavigationView { ExploreView() } TabbedView(selection: $selection) {
.tabItemLabel(Text("Explore")) ExploreView()
.tag(Tab.explore) .tabItemLabel(Text("Explore"))
NavigationView { HikesView() } .tag(Tab.explore)
.tabItemLabel(Text("Hikes")) HikesView()
.tag(Tab.hikes) .tabItemLabel(Text("Hikes"))
NavigationView { ToursView() } .tag(Tab.hikes)
.tabItemLabel(Text("Tours")) ToursView()
.tag(Tab.tours) .tabItemLabel(Text("Tours"))
} .tag(Tab.tours)
}
}
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView(selection: $selection) { NavigationView {


NavigationView { ExploreView() } TabbedView(selection: $selection) {
.tabItemLabel(Text("Explore")) ExploreView()
.tag(Tab.explore) .tabItemLabel(Text("Explore"))
NavigationView { HikesView() } .tag(Tab.explore)
.tabItemLabel(Text("Hikes")) HikesView()
.tag(Tab.hikes) .tabItemLabel(Text("Hikes"))
NavigationView { ToursView() } .tag(Tab.hikes)
.tabItemLabel(Text("Tours")) ToursView()
.tag(Tab.tours) .tabItemLabel(Text("Tours"))
} .tag(Tab.tours)
}
}
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView(selection: $selection) { NavigationView {


NavigationView { ExploreView() } TabbedView(selection: $selection) {
.tabItemLabel(Text("Explore")) ExploreView()
.tag(Tab.explore) .tabItemLabel(Text("Explore"))
NavigationView { HikesView() } .tag(Tab.explore)
.tabItemLabel(Text("Hikes")) HikesView()
.tag(Tab.hikes) .tabItemLabel(Text("Hikes"))
NavigationView { ToursView() } .tag(Tab.hikes)
.tabItemLabel(Text("Tours")) ToursView()
.tag(Tab.tours) .tabItemLabel(Text("Tours"))
} .tag(Tab.tours)
}
}
tvOS vs. iOS Navigation Hierarchies

iOS tvOS

TabbedView(selection: $selection) { NavigationView {


NavigationView { ExploreView() } TabbedView(selection: $selection) {
.tabItemLabel(Text("Explore")) ExploreView()
.tag(Tab.explore) .tabItemLabel(Text("Explore"))
NavigationView { HikesView() } .tag(Tab.explore)
.tabItemLabel(Text("Hikes")) HikesView()
.tag(Tab.hikes) .tabItemLabel(Text("Hikes"))
NavigationView { ToursView() } .tag(Tab.hikes)
.tabItemLabel(Text("Tours")) ToursView()
.tag(Tab.tours) .tabItemLabel(Text("Tours"))
} .tag(Tab.tours)
}
}

Demo

SwiftUI on Mac

Jeff Nadeau, macOS Frameworks


High information density


Multiple windows

Keyboard shortcuts

Touch Bar

High information density


Multiple windows

Keyboard shortcuts

Touch Bar
High Information Density

Provide more information at a glance


High Information Density

Provide more information at a glance

Precision pointing device allows smaller controls


High Information Density

Provide more information at a glance

Precision pointing device allows smaller controls


High Information Density

Provide more information at a glance

Precision pointing device allows smaller controls

Higher tolerance for large amounts of text


High Information Density

Provide more information at a glance Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Curabitur consectetur tincidunt mollis. Vivamus
ipsum nulla, sagittis id pellentesque ac, suscipit in
Precision pointing device allows smaller controls dui. Donec pretium suscipit blandit. Donec volutpat
mollis nulla. Proin a dapibus lorem. Morbi id tempor
nunc. Mauris tempus lacinia ligula in faucibus.
Higher tolerance for large amounts of text Quisque nec maximus augue. Nunc eu ornare nulla.
Suspendisse quam est, faucibus nec imperdiet sed,
sagittis at purus.

Nam mollis, lorem sed pretium efficitur, mauris leo


luctus elit, volutpat consectetur turpis libero vel
ante. Nulla non malesuada leo. Aenean ut interdum
turpis. Nunc sit amet euismod lorem, suscipit
venenatis nibh. Vestibulum euismod facilisis nisl nec
tincidunt. Integer massa ex, commodo vel finibus id,
cursus id erat. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia Curae;
Maecenas ligula ante, facilisis id tristique nec,
eleifend vitae neque.
High Information Density
High Information Density

Spacing and padding automatically adapt


High Information Density

Spacing and padding automatically adapt

Use .controlSize() for compact controls


High information density


Multiple windows

Keyboard shortcuts

Touch Bar
Multiple Windows
Multiple Windows

Compare content across windows side-by-side


Multiple Windows

Compare content across windows side-by-side

Focus on a single item in its own window


Multiple Windows

Compare content across windows side-by-side

Focus on a single item in its own window

Spatially organize windows around the Desktop and Spaces


High information density


Multiple windows

Keyboard shortcuts

Touch Bar
Keyboard Shortcuts
Keyboard Shortcuts

Quick access to common actions


Keyboard Shortcuts

Quick access to common actions

Lightning-fast navigation
// Adding Keyboard Shortcuts

TabbedView(selection: $selectedTab) {
ExploreView().tag(Tab.explore).tabItemLabel(Text("Explore"))

HikesView().tag(Tab.hikes).tabItemLabel(Text(“Hikes"))

ToursView().tag(Tab.tours).tabItemLabel(Text(“Tours"))
}
Keyboard Shortcuts
Keyboard Shortcuts

extension Command {
static let showExplore = Command(Selector(("showExplore:")))
static let showHikes = Command(Selector(("showHikes:")))
static let showTours = Command(Selector(("showTours:")))
}
// Adding Keyboard Shortcuts

TabbedView(selection: $selectedTab) {
ExploreView().tag(Tab.explore).tabItemLabel(Text("Explore"))

HikesView().tag(Tab.hikes).tabItemLabel(Text(“Hikes"))

ToursView().tag(Tab.tours).tabItemLabel(Text(“Tours"))
}
// Adding Keyboard Shortcuts

TabbedView(selection: $selectedTab) {
ExploreView().tag(Tab.explore).tabItemLabel(Text("Explore"))

HikesView().tag(Tab.hikes).tabItemLabel(Text(“Hikes"))

ToursView().tag(Tab.tours).tabItemLabel(Text(“Tours"))
}
.onCommand(.showExplore) { self.selectedTab = .explore }
.onCommand(.showHikes) { self.selectedTab = .hikes }
.onCommand(.showTours) { self.selectedTab = .tours }
// Adding Keyboard Shortcuts

TabbedView(selection: $selectedTab) {
ExploreView().tag(Tab.explore).tabItemLabel(Text("Explore"))

HikesView().tag(Tab.hikes).tabItemLabel(Text(“Hikes"))

ToursView().tag(Tab.tours).tabItemLabel(Text(“Tours"))
}
.onCommand(.showExplore) { self.selectedTab = .explore }
.onCommand(.showHikes) { self.selectedTab = .hikes }
.onCommand(.showTours) { self.selectedTab = .tours }
// Adding Keyboard Shortcuts

TabbedView(selection: $selectedTab) {
ExploreView().tag(Tab.explore).tabItemLabel(Text("Explore"))

HikesView().tag(Tab.hikes).tabItemLabel(Text(“Hikes"))

ToursView().tag(Tab.tours).tabItemLabel(Text(“Tours"))
}
.onCommand(.showExplore) { self.selectedTab = .explore }
.onCommand(.showHikes) { self.selectedTab = .hikes }
.onCommand(.showTours) { self.selectedTab = .tours }

Integrating SwiftUI WWDC 2019


High information density


Multiple windows

Keyboard shortcuts

Touch Bar
// Adding Touch Bar Support

TouchBar {

}a
// Adding Touch Bar Support

TouchBar {
Button(action: toggleFavorite) {
Image(isFavorite ? "favorite" : "favorite-empty")
}a

}a
// Adding Touch Bar Support

TouchBar {
Button(action: toggleFavorite) {
Image(isFavorite ? "favorite" : "favorite-empty")
}a

Button(action: placeCall) {
Image("call")
}a

}a
// Adding Touch Bar Support

TouchBar {
Button(action: toggleFavorite) {
Image(isFavorite ? "favorite" : "favorite-empty")
}a

Button(action: placeCall) {
Image("call")
}a

Button(action: getDirections) {
Text("Get Directions")
}a
}a
// Adding Touch Bar Support

MyCustomView() .touchBar(

TouchBar {
Button(action: toggleFavorite) {
Image(isFavorite ? "favorite" : "favorite-empty")
}a

Button(action: placeCall) {
Image("call")
}a

Button(action: getDirections) {
Text("Get Directions")
}a
}a
)
// Adding Touch Bar Support

MyCustomView() .touchBar(

TouchBar {
Button(action: toggleFavorite) {
Image(isFavorite ? "favorite" : "favorite-empty")
}a

Button(action: placeCall) {
Image("call")
}a

Button(action: getDirections) {
Text("Get Directions")
}a
}a
)

Demo

SwiftUI on Apple Watch

Meghna Sapre, watchOS Frameworks


watchOS App

Interactive Notifications

Landmarks on Apple Watch


3
Taps or fewer
watchOS App
watchOS App

ScrollView
watchOS App
watchOS App

.digitalCrownRotation
watchOS App

.digitalCrownRotation
watchOS App
watchOS App

HStack
VStack
watchOS App
watchOS App

List
Section

watchOS App

Interactive Notifications

Landmarks on Apple Watch


Interactive Notifications
Interactive Notifications

Provide useful information


Interactive Notifications

Provide useful information

Offer intuitive actions


Interactive Notifications

Provide useful information

Offer intuitive actions

Deliver at the right time


watchOS App

Interactive Notifications

Landmarks on Apple Watch


Landmarks on Apple Watch
Landmarks on Apple Watch
Landmarks on Apple Watch
Landmarks on Apple Watch
Landmarks on Apple Watch

ForEach(landmarks) { landmark in

WatchLandmarkDetails(landmark: landmark)
}
Landmarks on Apple Watch

// WatchLandmarkDetails

// Image
LandmarkImage(landmark: landmark)

// Details
NavigationButton(destination: WatchTourDetails(landmark:
landmark)) {
Text("Tour: 10:00 AM")
}

// Make a Call
Button(action: call) {
Image(systemName: "phone.fill")
.foregroundColor(.green)
}
Landmarks on Apple Watch
Landmarks on Apple Watch
Landmarks on Apple Watch

var landmarks: [Landmark] {


if showFavoritesOnly {
return landmarkData.filter(isFavorite)
}
return landmarkData
}
Landmarks on Apple Watch

var landmarks: [Landmark] {


if showFavoritesOnly {
return landmarkData.filter(isFavorite)
}
return landmarkData
}

Button(action: self.toggleFavoritesOnly) {

Text(self.userData.showFavoritesOnly ?

"Show All" : "Show Favorites")


}
Landmarks on Apple Watch

return landmarkList
Landmarks on Apple Watch

return landmarkList
Landmarks on Apple Watch

return landmarkList
.listStyle(.carousel)
Interactive Notifications
Interactive Notifications

Demo
Summary
Summary

Take a design-first approach


Summary

Take a design-first approach

Effortlessly share model code


Summary

Take a design-first approach

Effortlessly share model code

Be judicious when sharing view code


Summary

Take a design-first approach

Effortlessly share model code

Be judicious when sharing view code

Learn once, apply anywhere


More Information
developer.apple.com/wwdc19/240

You might also like