-
Build SwiftUI apps for tvOS
Add a new dimension to your tvOS app with SwiftUI. We'll show you how to build layouts powered by SwiftUI and customize your interface with custom buttons, provide more functionality in your app with a context menu, check if views are focused, and manage default focus.
To get the most out of this session, you should be comfortable with SwiftUI. For a primer, watch “Introducing SwiftUI: Building Your First App” and “SwiftUI On All Devices.”Recursos
- Supporting Multiple Users in Your tvOS App
- isFocused
- prefersDefaultFocus(_:in:)
- CardButtonStyle
- Learn to Make Apps with SwiftUI
- SwiftUI
- Human Interface Guidelines: Designing for tvOS
Videos relacionados
WWDC20
WWDC19
-
Buscar este video…
-
-
1:42 - CardButtonStyle
Button(albumLabel, action: playAlbum) .buttonStyle(CardButtonStyle()) -
2:24 - Custom Button Styles
struct MyNewButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .background(configuration.isPressed ? … : …) // Custom styling } } Button(albumLabel, action: playAlbum) .buttonStyle(MyNewButtonStyle()) -
3:19 - Context Menus
AlbumView() .contextMenu { Button("Add to Favorites", action: addAlbumToFavorites) Button("View Artist", action: viewArtistPage) Button("Discover Similar Albums", action: viewSimilarAlbums) } -
5:47 - isFocused Environment Variable
struct SongView: View { var body: some View { Button(action: playSong) { VStack { Image(albumArt) DetailsView(...) } }.buttonStyle(MyCustomButtonStyle()) } } struct DetailsView: View { ... @Environment(\.isFocused) var isFocused: Bool var body: some View { VStack { Text(songName) Text(isFocused ? artistAndAlbum : artistName) } } } -
8:42 - Login Screen (Default Focus)
var body: some View { VStack { TextField("Username", text: $username) SecureField("Password", text: $password) Button("Log In", action: logIn) } } -
8:51 - Default Focus
@Namespace private var namespace @State private var areCredentialsFilled: Bool var body: some View { VStack { TextField("Username", text: $username) .prefersDefaultFocus(!areCredentialsFilled, in: namespace) SecureField("Password", text: $password) Button("Log In", action: logIn) .prefersDefaultFocus(areCredentialsFilled, in: namespace) } .focusScope(namespace) } -
11:12 - Reset Focus
@Namespace private var namespace @State private var areCredentialsFilled: Bool @Environment(\.resetFocus) var resetFocus var body: some View { VStack { TextField("Username", text: $username) .prefersDefaultFocus(!areCredentialsFilled, in: namespace) SecureField("Password", text: $password) Button("Log In", action: logIn) .prefersDefaultFocus(areCredentialsFilled, in: namespace) Button("Clear", action: { username = ""; password = "" areCredentialsFilled = false resetFocus(in: namespace) }) } .focusScope(namespace) } -
12:45 - Lazy Grids
struct ShelfView: View { var body: some View { ScrollView([.horizontal]) { LazyHGrid(rows: [GridItem()]) { ForEach(playlists, id: \.self) { playlist in Button(action: goToPlaylist) { Image(playlist.coverImage) .resizable() .frame(…) } .buttonStyle(CardButtonStyle()) } } } } }
-