Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftUI Navigation のすべて

Avatar for Aikawa Aikawa
September 10, 2022

SwiftUI Navigation のすべて

iOSDC Japan 2022 で発表した内容です

Avatar for Aikawa

Aikawa

September 10, 2022
Tweet

More Decks by Aikawa

Other Decks in Programming

Transcript

  1. ΞδΣϯμ • SwiftUI Navigation ͷ၆ᛌ • ༷ʑͳछྨ ͷ Navigation •

    OS ʹΑΔมԽ͕ܹ͍͠ Navigation • Fire and forget / State driven Navigation API • SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ • Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ • ʮswiftui-navigationʯͷΞϓϩʔν • ·ͱΊ 3
  2. ༷ʑͳछྨͷ Navigation API ͕ଘࡏ͢Δ • Tab • Alert • Sheet

    • Full Screen Cover • Con fi rmation Dialog • Popover • Navigation Link… SwiftUI Navigation ͷ၆ᛌ > ༷ʑͳछྨͷ Navigation 8
  3. Tab TabView { FirstView() .tabItem { Image(systemName: "exclamationmark.circle") Text("Alert") }

    SecondView() .tabItem {…} ThirdView() .tabItem {…} FourthView() .tabItem {…} } SwiftUI Navigation ͷ၆ᛌ > ༷ʑͳछྨͷ Navigation
  4. NavigationViewɾNavigationLink (Deprecated) NavigationView { ForEach(1...10, id: \.self) { id in

    NavigationLink( "Go to \(id) simple destination", destination: { Text("This is \(id) destination") } ) } } SwiftUI Navigation ͷ၆ᛌ > ༷ʑͳछྨͷ Navigation
  5. OS ͕ਐԽ͢ΔʹͭΕ API ͷܗ΋มΘ͖ͬͯͨ • ActionSheet API (deprecated) → Con

    fi rmation Dialog API • Alert API • deprecated ʹͳͬͨ΋ͷͱɺͦ͏Ͱͳ͍΋ͷ͕͋Δ • Navigation-base API • NavigationView → NavigationStack • NavigationLink 14 SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  6. ActionSheet API (deprecated) .actionSheet(isPresented: $showActionSheet) { ActionSheet( title: Text(...), message:

    Text(...), buttons: [ .cancel(), .destructive( Text(...), action: {} ), .default( Text(...), action: {} ) ] ) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  7. ActionSheet API (deprecated) .actionSheet(isPresented: $showActionSheet) { ActionSheet( title: Text(...), message:

    Text(...), buttons: [ .cancel(), .destructive( Text(...), action: {} ), .default( Text(...), action: {} ) ] ) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  8. ActionSheet API (deprecated) .actionSheet(isPresented: $showActionSheet) { ActionSheet( title: Text(...), message:

    Text(...), buttons: [ .cancel(), .destructive( Text(...), action: {} ), .default( Text(...), action: {} ) ] ) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  9. Con fi rmation Dialog API(iOS 15~) .confirmationDialog( “Title", isPresented: $isConfirming

    presenting: dialogDetail ) { detail in Button { } label: { Text("Import \(detail.name)") } Button("Cancel", role: .cancel) { dialogDetail = nil } } message: { detail in Text(\(detail.name) \(detail.type)) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  10. Con fi rmation Dialog API(iOS 15~) .confirmationDialog( “Title", isPresented: $isConfirming,

    presenting: dialogDetail ) { detail in Button { } label: { Text("Import \(detail.name)") } Button("Cancel", role: .cancel) { dialogDetail = nil } } message: { detail in Text(\(detail.name) \(detail.type)) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  11. Con fi rmation Dialog API(iOS 15~) .confirmationDialog( “Title", isPresented: $isConfirming,

    presenting: dialogDetail ) { detail in Button { } label: { Text("Import \(detail.name)") } Button("Cancel", role: .cancel) { dialogDetail = nil } } message: { detail in Text(\(detail.name) \(detail.type)) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  12. Alert API (deprecated) .alert(isPresented: $showAlert) { Alert( title: Text("Title"), message:

    Text("Message") ) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  13. Alert API (deprecated) .alert(item: $alertDetails) { details in Alert( title:

    Text("Title"), message: Text(""" Imported \(details.name) \n Filetype: \(details.fileType). """), dismissButton: .default(Text("Dismiss")) ) } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  14. Alert API (iOS 15~) .alert( "Alert͕දࣔ͞Ε·ͨ͠", isPresented: $isPresentedAlert, actions: {

    Button("OK", action: {}) } ) SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  15. NavigationViewɾOld NavigationLink (deprecated) NavigationView { List(model.notes) { note in NavigationLink(

    note.title, destination: NoteEditor(id: note.id) ) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  16. NavigationViewɾOld NavigationLink (deprecated) NavigationView { List(model.notes) { note in NavigationLink(

    note.title, destination: NoteEditor(id: note.id) ) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  17. NavigationViewɾOld NavigationLink (deprecated) NavigationView { List(model.notes) { note in NavigationLink(

    note.title, // ભҠݩͷ View ʹදࣔ͞ΕΔ title destination: NoteEditor(id: note.id) // ભҠޙͷը໘ ) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  18. Simple NavigationStackɾNew NavigationLink NavigationStack { List(parks) { park in NavigationLink(

    park.name, value: park ) } .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  19. Simple NavigationStackɾNew NavigationLink NavigationStack { List(parks) { park in NavigationLink(

    park.name, value: park ) } .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  20. Simple NavigationStackɾNew NavigationLink NavigationStack { List(parks) { park in NavigationLink(

    park.name, // ભҠݩͷը໘ʹදࣔ͢Δ title value: park // ೚ҙͷܕͷ value ) } .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  21. Simple NavigationStackɾNew NavigationLink NavigationStack { List(parks) { park in NavigationLink(

    park.name, value: park ) } // value ͷܕʹԠͯ͡ navigationDestination ͕൓Ԡ͢Δ .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  22. Binding NavigationStackɾNew NavigationLink @State private var presentedParks: [Park] = []

    // ... NavigationStack(path: $presentedParks) { List(parks) { park in NavigationLink(park.name, value: park) } .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  23. Binding NavigationStackɾNew NavigationLink @State private var presentedParks: [Park] = []

    // ... NavigationStack(path: $presentedParks) { List(parks) { park in NavigationLink(park.name, value: park) } .navigationDestination(for: Park.self) { park in ParkDetails(park: park) } } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation
  24. Binding NavigationStackɾNew NavigationLink @State private var presentedParks: [Park] = []

    // ... NavigationStack(path: $presentedParks) { // ... } func showParks() { // RootView -> Park("Yosemite") -> Park("Sequoia") presentedParks = [Park("Yosemite"), Park("Sequoia")] } SwiftUI Navigation ͷ၆ᛌ > OS ʹΑΔมԽ͕ܹ͍͠ Navigation ※ iOS 16 ͷ API ʹ͍ͭͯͷ FB: https://gist.github.com/mbrandonw/f8b94957031160336cac6898a919cbb7
  25. Navigation API ͸େ͖͘ 2 ͭʹ෼ྨͰ͖Δ • ʮswiftui-navigationʯREADME ͔ΒҾ༻ • Fire

    and forget Navigation API • State driven Navigation API 35 SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  26. Navigation API ͸େ͖͘ 2 ͭʹ෼ྨͰ͖Δ • Fire and forget Navigation

    API • State driven Navigation API 36 SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  27. Fire and forget Navigation API • Binding Ҿ਺ΛऔΒͳ͍ • SwiftUI

    ͕ Navigation ͷঢ়ଶΛ׬શʹ಺෦Ͱ؅ཧ͢Δ • Navigation Λૉૣ࣮͘ݱͰ͖Δ͕ɺNavigation ʹରͯ͠ 
 ϓϩάϥϜతͳ੍ޚ͕Ͱ͖ͳ͘ͳΔ 37 SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  28. Fire and forget API - Tab - TabView { ReceivedView()

    .tabItem { // ... } SentView() .tabItem { // ... } AccountView() .tabItem { // ... } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  29. Fire and forget API - Tab - // Binding Ҿ਺ΛऔΒͳ͍ɻλοϓͰ͔͠

    navigation Ͱ͖ͳ͍ TabView { ReceivedView() .tabItem { // ... } SentView() .tabItem { // ... } AccountView() .tabItem { // ... } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  30. Fire and forget API - NavigationLink - NavigationView { List(model.notes)

    { note in NavigationLink( note.title, destination: NoteEditor(id: note.id) ) } Text("Select a Note") } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  31. Fire and forget API - NavigationLink - NavigationView { List(model.notes)

    { note in // Binding Ҿ਺ΛऔΒͳ͍ɻλοϓͰ͔͠ navigation Ͱ͖ͳ͍ NavigationLink( note.title, destination: NoteEditor(id: note.id) ) } Text("Select a Note") } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  32. Navigation API ͸େ͖͘ 2 ͭʹ෼ྨͰ͖Δ • Fire and forget Navigation

    API • State driven Navigation API 42 SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  33. State driven Navigation API • Binding Ҿ਺ΛऔΔ • Navigation Λ༗ޮɾແޮʹ͢Δ࣌ʹυϝΠϯͷঢ়ଶ΋มߋͰ͖Δ

    • Fire and forget API ΑΓෳࡶͰ͸͋Δ͕ɺϓϩάϥϜతͳ੍ޚ͕ 
 ՄೳͱͳΔͨΊɺ࢖͍ํʹΑͬͯ͸ Deep Link ͳͲ΋࣮ݱͰ͖Δ 43 SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  34. State driven API - Tab - struct ContentView: View {

    @State var selectedTab: Tab = .received var body: some View { TabView(selection: $selectedTab) { ReceivedView().tabItem { ... } .tag(Tab.received) SentView().tabItem { ... } .tag(Tab.sent) AccountView().tabItem { ... } .tag(Tab.account) } } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  35. State driven API - Tab - struct ContentView: View {

    @State var selectedTab: Tab = .received var body: some View { TabView(selection: $selectedTab) { ReceivedView().tabItem { ... } .tag(Tab.received) SentView().tabItem { ... } .tag(Tab.sent) AccountView().tabItem { ... } .tag(Tab.account) } } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  36. State driven API - Tab - struct ContentView: View {

    @State var selectedTab: Tab = .sent var body: some View { TabView(selection: $selectedTab) { ReceivedView().tabItem { ... } .tag(Tab.received) SentView().tabItem { ... } .tag(Tab.sent) AccountView().tabItem { ... } .tag(Tab.account) } } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  37. ҟͳΔ View ͰแΉͱ Deep Link Ͱ͖ͳ͍ struct ContainerView: View {

    var body: some View { ContentView(selectedTab: .received) } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  38. ContainerView ʹঢ়ଶΛ࣋ͨͤͯղܾ͢Δʁ struct ContainerView: View { let selectedTab: Tab var

    body: some View { ContentView(selectedTab: selectedTab) } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  39. ContainerView ʹঢ়ଶΛ࣋ͨͤͯղܾ͢Δʁ struct ContainerView: View { // ContainerView ʹؔ܎ͳ͍ Tab

    ͷঢ়ଶΛ࣋ͨͤΔͷ͸ඍົ // ͔͠΋ ContentView ͷ selectedTab ͸ @State ͳͷͰޡΓ let selectedTab: Tab var body: some View { ContentView(selectedTab: selectedTab) } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  40. ΞϓϦͷঢ়ଶΛ؅ཧ͢Δ ViewModel Λಋೖ͠ 
 ղܾ͢Δ class AppViewModel: ObservableObject { @Published

    var selectedTab: Tab init(selectedTab: Tab = .received) { self.selectedTab = selectedTab } } SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  41. ΞϓϦͷঢ়ଶΛ؅ཧ͢Δ ViewModel Λಋೖ͠ 
 ղܾ͢Δ struct ContentView: View { @ObservedObject

    var viewModel: AppViewModel var body: some View { TabView(selection: $viewModel.selectedTab) { // ... } } } // ContentView ͷ initialize ࣌ʹ Tab Λૢ࡞Ͱ͖ΔΑ͏ʹͳͬͨ ContentView(viewModel: .init(selectedTab: .two)) SwiftUI Navigation ͷ၆ᛌ > Fire and forget / State driven Navigation API
  42. Navigation API ʹ͓͚Δ՝୊ 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ

    API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊
  43. Navigation API ʹ͓͚Δ՝୊ 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ

    API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍
  44. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛ උ͍͑ͯͳ͍ struct ContentView: View { @State

    var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍
  45. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛ උ͍͑ͯͳ͍ struct ContentView: View { @State

    var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍
  46. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛ උ͍͑ͯͳ͍ struct ContentView: View { @State

    var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ Binding ValueΛ EditPostViewʹ
 ౉ͤͳ͍ EditPostViewͰͷ มߋ͕ContentView ʹ൓ө͞Εͳ͍
  47. Navigation API ʹ͓͚Δ՝୊ 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ

    API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  48. Deprecated / New Alert API // Deprecated API // Binding<Bool>

    Λड͚औΔ func alert( isPresented: Binding<Bool>, content: () -> Alert ) -> some View // Binding<Item?> Λड͚औΔ func alert<Item>( item: Binding<Item?>, content: (Item) -> Alert ) -> some View where Item : Identifiable // New API // Binding<Bool> Λड͚औΔ func alert<A>( _ title: Text, isPresented: Binding<Bool>, actions: () -> A ) -> some View where A : View // Binding<Bool> ͱ data Λड͚औΔ func alert<A, T>( _ title: Text, isPresented: Binding<Bool>, presenting data: T?, actions: (T) -> A ) -> some View where A : View SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  49. Deprecated / New Alert API // Deprecated API // Binding<Bool>

    Λड͚औΔ func alert( isPresented: Binding<Bool>, content: () -> Alert ) -> some View // Binding<Item?> Λड͚औΔ func alert<Item>( item: Binding<Item?>, content: (Item) -> Alert ) -> some View where Item : Identifiable // New API // Binding<Bool> Λड͚औΔ func alert<A>( _ title: Text, isPresented: Binding<Bool>, actions: () -> A ) -> some View where A : View // Binding<Bool> ͱ data Λड͚औΔ func alert<A, T>( _ title: Text, isPresented: Binding<Bool>, presenting data: T?, actions: (T) -> A ) -> some View where A : View SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  50. Deprecated boolean binding API struct ExampleView: View { @State private

    var showAlert = false var body: some View { BaseView(...) .alert(isPresented: $showAlert) { Alert(...) } } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  51. Deprecated / New Alert API // Deprecated API // Binding<Bool>

    Λड͚औΔ func alert( isPresented: Binding<Bool>, content: () -> Alert ) -> some View // Binding<Item?> Λड͚औΔ func alert<Item>( item: Binding<Item?>, content: (Item) -> Alert ) -> some View where Item : Identifiable // New API // Binding<Bool> Λड͚औΔ func alert<A>( _ title: Text, isPresented: Binding<Bool>, actions: () -> A ) -> some View where A : View // Binding<Bool> ͱ data Λड͚औΔ func alert<A, T>( _ title: Text, isPresented: Binding<Bool>, presenting data: T?, actions: (T) -> A ) -> some View where A : View SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  52. Deprecated optional item binding API struct ExampleView: View { @State

    private var item: Item? var body: some View { BaseView(...) .alert(item: $item) { item in Alert(...) // item Λར༻ͯ͠ alert ΛΧελϚΠζͰ͖Δ } } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  53. Deprecated / New Alert API // Deprecated API // Binding<Bool>

    Λड͚औΔ func alert( isPresented: Binding<Bool>, content: () -> Alert ) -> some View // Binding<Item?> Λड͚औΔ func alert<Item>( item: Binding<Item?>, content: (Item) -> Alert ) -> some View where Item : Identifiable // New API // Binding<Bool> Λड͚औΔ func alert<A>( _ title: Text, isPresented: Binding<Bool>, actions: () -> A ) -> some View where A : View // Binding<Bool> ͱ data Λड͚औΔ func alert<A, T>( _ title: Text, isPresented: Binding<Bool>, presenting data: T?, actions: (T) -> A ) -> some View where A : View SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  54. New boolean binding API struct ExampleView: View { @State private

    var showAlert = false var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, action: { ... } ) } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  55. Deprecated / New Alert API // Deprecated API // Binding<Bool>

    Λड͚औΔ func alert( isPresented: Binding<Bool>, content: () -> Alert ) -> some View // Binding<Item?> Λड͚औΔ func alert<Item>( item: Binding<Item?>, content: (Item) -> Alert ) -> some View where Item : Identifiable // New API // Binding<Bool> Λड͚औΔ func alert<A>( _ title: Text, isPresented: Binding<Bool>, actions: () -> A ) -> some View where A : View // Binding<Bool> ͱ data Λड͚औΔ func alert<A, T>( _ title: Text, isPresented: Binding<Bool>, presenting data: T?, actions: (T) -> A ) -> some View where A : View SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  56. New boolean binding and optional item API struct ExampleView: View

    { @State private var showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  57. New boolean binding and optional item API struct ExampleView: View

    { @State private var showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ 􀁣 showAlert: true item: non null
  58. New boolean binding and optional item API struct ExampleView: View

    { @State private var showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ 􀁡 showAlert: true item: null
  59. New boolean binding and optional item API ͸ 
 ঢ়ଶ؅ཧΛෳࡶʹͤͯ͞͠·͏

    • ։ൃऀ͕ҎԼͷঢ়ଶͷ੔߹ੑΛؾʹ͠ͳ͚Ε͹͍͚ͳ͍ͷ͕ਏ͍ • Alert Λදࣔ͢ΔͨΊͷ boolean binding • Alert ͷ಺༰Λ࡞ΔͨΊͷ optional item • Navigation ͕γϯϓϧͳ͏ͪ͸ͦ͜·ͰࠔΒͳ͍͔΋͠Εͳ͍͕ɺ 
 Navigation ͕૿͑Ε͹༰қʹঢ়ଶ؅ཧ΋ෳࡶʹͳͬͯ͠·͏ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ
  60. Navigation API ʹ͓͚Δ՝୊ 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ

    API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  61. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱ 
 ແବͳঢ়ଶ͕૿͑Δ struct ContentView: View { @State

    var draft: Post? @State var settings: Settings? @State var userProfile: Profile? var body: some View { BaseView(...) .sheet(item: self.$draft) { (draft: Post) in EditPostView(post: draft) } .sheet(item: self.$settings) { (settings: Settings) in SettingsView(settings: settings) } .sheet(item: self.$userProfile) { (userProfile: Profile) in UserProfile(profile: userProfile) } } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  62. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱ 
 ແବͳঢ়ଶ͕૿͑Δ struct ContentView: View { @State

    var draft: Post? @State var settings: Settings? @State var userProfile: Profile? var body: some View { BaseView(...) .sheet(item: self.$draft) { (draft: Post) in EditPostView(post: draft) } .sheet(item: self.$settings) { (settings: Settings) in SettingsView(settings: settings) } .sheet(item: self.$userProfile) { (userProfile: Profile) in UserProfile(profile: userProfile) } } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  63. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱ 
 ແବͳঢ়ଶ͕૿͑Δ struct ContentView: View { @State

    var draft: Post? // null + non null = 2 @State var settings: Settings? // null + non null = 2 @State var userProfile: Profile? // null + non null = 2 var body: some View { BaseView(...) .sheet(item: self.$draft) { (draft: Post) in EditPostView(post: draft) } .sheet(item: self.$settings) { (settings: Settings) in SettingsView(settings: settings) } .sheet(item: self.$userProfile) { (userProfile: Profile) in UserProfile(profile: userProfile) } } } SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  64. ༷ʑͳύλʔϯͷঢ়ଶ͕ൃੜͯ͠͠·͏ %SBGU 4FUUJOHT 1SP fi MF ύλʔϯ /VMM /VMM /VMM

    ύλʔϯ /POOVMM /VMM /VMM ύλʔϯ /VMM /POOVMM /VMM ύλʔϯ /VMM /VMM /POOVMM ύλʔϯ /POOVMM /POOVMM /VMM ύλʔϯ /POOVMM /VMM /POOVMM ύλʔϯ /VMM /POOVMM /POOVMM ύλʔϯ /POOVMM /POOVMM /POOVMM SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  65. ༷ʑͳύλʔϯͷঢ়ଶ͕ൃੜͯ͠͠·͏ %SBGU 4FUUJOHT 1SP fi MF ύλʔϯ /VMM /VMM /VMM

    ύλʔϯ /POOVMM /VMM /VMM ύλʔϯ /VMM /POOVMM /VMM ύλʔϯ /VMM /VMM /POOVMM ύλʔϯ /POOVMM /POOVMM /VMM ύλʔϯ /POOVMM /VMM /POOVMM ύλʔϯ /VMM /POOVMM /POOVMM ύλʔϯ /POOVMM /POOVMM /POOVMM ༗ޮͳঢ়ଶ͸͜ΕΒͷΈ SwiftUI ͷ Navigation API ʹ͓͚Δ՝୊ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ
  66. Navigation API ʹ͓͚Δ՝୊ 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ

    API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔
  67. ʮswiftui-navigation ʯͷΞϓϩʔν 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • Binding value

    Λ౉͢͜ͱ͕Ͱ͖Δ API overloads 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔
  68. swiftui-navigation ͱ͸ʁ • SwiftUI ͷ Navigation ʹ focus ͨ͠ Point-Free

    ੡ͷϥΠϒϥϦ • SwiftUI ͷ Navigation Λར༻͢Δࡍͷ༷ʑͳ՝୊Λղܾ͢ΔͨΊʹҎԼͷ 3 ͭͷπʔϧΛఏڙ͍ͯ͠Δ • Navigation API overloads • ͜ͷޙ࿩͠·͢ • Navigation views ( `IfLet`, `IfCaseLet`, `Switch`/`CaseLet` ) • ໊લͷ௨Γͷ View ܈ɻBinding value Λѻ͑ΔΑ͏ʹઃܭ͞Ε͍ͯΔ • Binding transformations • ಠࣗͷ Navigation Λ࡞Δࡍʹ༗༻ͳπʔϧ Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔
  69. ʮswiftui-navigation ʯͷΞϓϩʔν 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • Binding value

    Λ౉͢͜ͱ͕Ͱ͖Δ API overloads 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔
  70. ʮswiftui-navigation ʯͷΞϓϩʔν 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • Binding value

    Λ౉͢͜ͱ͕Ͱ͖Δ API overloads 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  71. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛ උ͍͑ͯͳ͍ struct ContentView: View { @State

    var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  72. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛ උ͍͑ͯͳ͍ struct ContentView: View { @State

    var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads Binding ValueΛ EditPostViewʹ
 ౉ͤͳ͍ EditPostViewͰͷ มߋ͕ContentView ʹ൓ө͞Εͳ͍
  73. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ struct ContentView: View {

    @State var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { (draft: Post) in EditPostView(post: draft) } } } struct EditPostView: View { let post: Post var body: some View { ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  74. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ struct ContentView: View {

    @State var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { ($draft: Post) in // closure ʹ Binding value Λ౉ͤΔΑ͏ʹͳͬͨΒྑͦ͞͏ EditPostView(post: $draft) } } } struct EditPostView: View { @Binding var post: Post var body: some View { ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  75. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ extension View { func

    sheet<Value, Content>( unwrapping optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in // Binding<Value?> Λ Binding<Value> ʹม׵͢Δ value = ??? content(value) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  76. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ extension View { func

    sheet<Value, Content>( unwrapping optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in // Binding<Value?> Λ Binding<Value> ʹม׵͢Δ value = ??? content(value) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  77. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ extension View { func

    sheet<Value, Content>( unwrapping optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in // Binding<Value?> Λ Binding<Value> ʹม׵͢Δ value = ??? content(value) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  78. Binding Value Λ౉ͤΔ sheet API Λߟ͑Δ extension View { func

    sheet<Value, Content>( unwrapping optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in // Binding<Value?> Λ Binding<Value> ʹม׵͢Δ value = ??? content(value) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  79. Binding<Value?> Λ Binding<Value> ʹม׵͢Δ extension Binding { init?(unwrapping binding: Binding<Value?>)

    { guard let wrappedValue = binding.wrappedValue else { return nil } self.init( get: { wrappedValue }, set: { binding.wrappedValue = $0 } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads ※ Binding failable initializer ͸ඪ४Ͱଘࡏ͢Δ͕ɺόά͕͋Δ: https://gist.github.com/stephencelis/3a232a1b718bab0ae1127ebd5fcf6f97
  80. Binding<Value?> Λ Binding<Value> ʹม׵͢Δ extension Binding { init?(unwrapping binding: Binding<Value?>)

    { guard let wrappedValue = binding.wrappedValue else { return nil } self.init( get: { wrappedValue }, set: { binding.wrappedValue = $0 } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  81. Binding<Value?> Λ Binding<Value> ʹม׵͢Δ extension Binding { init?(unwrapping binding: Binding<Value?>)

    { guard let wrappedValue = binding.wrappedValue else { return nil } self.init( get: { wrappedValue }, set: { binding.wrappedValue = $0 } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  82. Binding<Value?> Λ Binding<Value> ʹม׵͢Δ extension Binding { init?(unwrapping binding: Binding<Value?>)

    { guard let wrappedValue = binding.wrappedValue else { return nil } self.init( get: { wrappedValue }, set: { binding.wrappedValue = $0 } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  83. ࡞੒ͨ͠ init?(unwrapping:) Λద༻͢Δ extension View { func sheet<Value, Content>( unwrapping

    optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in if let value = Binding(unwrapping: optionalValue) { content(value) } } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  84. ࡞੒ͨ͠ init?(unwrapping:) Λద༻͢Δ extension View { func sheet<Value, Content>( unwrapping

    optionalValue: Binding<Value?>, @ViewBuilder content: @escaping (Binding<Value>) -> Content ) -> some View where Value: Identifiable, Content: View { self.sheet(item: optionalValue) { _ in if let value = Binding(unwrapping: optionalValue) { content(value) } } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads
  85. Before / After struct ContentView: View { @State var draft:

    Post? var body: some View { Button("Edit") { draft = Post() } .sheet(unwrapping: $draft) { $draft in EditPostView(post: $draft) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ > Binding value Λ౉͢͜ͱ͕Ͱ͖Δ API overloads struct ContentView: View { @State var draft: Post? var body: some View { Button("Edit") { draft = Post() } .sheet(item: $draft) { draft in EditPostView(post: draft) } } } #FGPSF "GUFS
  86. ʮswiftui-navigation ʯͷΞϓϩʔν 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • Binding value

    Λ౉͢͜ͱ͕Ͱ͖Δ API overloads 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads
  87. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ struct ExampleView: View { @State private var

    showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads
  88. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ struct ExampleView: View { @State private var

    showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } 􀁣 showAlert: true item: non null Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads
  89. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ struct ExampleView: View { @State private var

    showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } 􀁡 showAlert: true item: null Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads
  90. ͳͥঢ়ଶ؅ཧΛෳࡶʹ͢Δ API ʹͳ͍ͬͯΔͷ͔ struct ExampleView: View { @State private var

    showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, // Alert Λදࣔ͢ΔͨΊͷ Boolean presenting: item // Alert ͷ಺༰ΛΧελϚΠζ͢ΔͨΊͷ optional item action: { item in ... }, message: { item in ... } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  91. ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API ͸ͲΜͳܗ͔ struct ExampleView: View { @State private var

    showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( title: { item in ... }, presenting: item // optional item ͷΈͰʮalert ͷදࣔ৚݅ʯʮalertͷ಺༰ʯΛܾΊΒΕΔ action: { item in ... }, message: { item in ... } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  92. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( ???, // alert title isPresented: ???, presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  93. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( ???, // alert title isPresented: ???, presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  94. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( ???, // alert title isPresented: ???, presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  95. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( data.wrappedValue.map(title) ?? Text(""), isPresented: ???, presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  96. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( data.wrappedValue.map(title) ?? Text(""), isPresented: ???, presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  97. Optional item ͷΈΛཁٻ͢Δ API Λߟ͑Δ extension View { func alert<A:

    View, M: View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( data.wrappedValue.map(title) ?? Text(""), isPresented: ???, // Binding<T?> Λ Binding<Bool> ʹม׵Ͱ͖Δͱྑͦ͞͏ presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  98. Binding<T?> Λ Binding<Bool> ʹม׵͢Δ extension Binding { func isPresented<Wrapped>() ->

    Binding<Bool> where Value == Wrapped? { .init( get: { self.wrappedValue != nil }, set: { isPresented in if !isPresented { self.wrappedValue = nil } } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  99. Binding<T?> Λ Binding<Bool> ʹม׵͢Δ extension Binding { func isPresented<Wrapped>() ->

    Binding<Bool> where Value == Wrapped? { // Binding<T?> Λม׵͢ΔͨΊͷ΋ͷͳͷͰɺoptional ʹݶఆ .init( get: { self.wrappedValue != nil }, set: { isPresented in if !isPresented { self.wrappedValue = nil } } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  100. Binding<T?> Λ Binding<Bool> ʹม׵͢Δ extension Binding { func isPresented<Wrapped>() ->

    Binding<Bool> where Value == Wrapped? { .init( get: { self.wrappedValue != nil }, set: { isPresented in // isPresent ͕ false = alert ͕ด͡ΒΕΔλΠϛϯά // ͦͷࡍ͸ Binding ࣗ਎Λ nil ʹ͢Δ͜ͱͰແޮͳঢ়ଶͷൃੜΛ๷͛Δ if !isPresented { self.wrappedValue = nil } } ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  101. ࡞੒ͨ͠ isPresented Λద༻͢Δ extension View { func alert<A: View, M:

    View, T>( title: (T) -> Text, presenting data: Binding<T?>, @ViewBuilder actions: @escaping (T) -> A, @ViewBuilder message: @escaping (T) -> M ) -> some View { self.alert( data.wrappedValue.map(title) ?? Text(""), isPresented: data.isPresented(), presenting: data.wrappedValue, actions: actions, message: message ) } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  102. Before / After struct ExampleView: View { @State private var

    item: Item? var body: some View { BaseView(...) .alert( Text($0.xxx), presenting: item action: { item in ... }, message: { item in ... } ) } } struct ExampleView: View { @State private var showAlert = false @State private var item: Item? var body: some View { BaseView(...) .alert( "Alert title", isPresented: $showAlert, presenting: item action: { item in ... }, message: { item in ... } ) } } #FGPSF "GUFS Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ > ঢ়ଶ؅ཧΛෳࡶʹͤ͞ͳ͍ API overloads
  103. ʮswiftui-navigation ʯͷΞϓϩʔν 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • Binding value

    Λ౉͢͜ͱ͕Ͱ͖Δ API overloads 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ࠷௿ݶͷঢ়ଶͷΈΛཁٻ͢Δ API overloads 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  104. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱ 
 ແବͳঢ়ଶ͕૿͑Δ struct ContentView: View { @State

    var draft: Post? // null + non null = 2 @State var settings: Settings? // null + non null = 2 @State var userProfile: Profile? // null + non null = 2 var body: some View { BaseView(...) .sheet(item: self.$draft) { (draft: Post) in EditPostView(post: draft) } .sheet(item: self.$settings) { (settings: Settings) in SettingsView(settings: settings) } .sheet(item: self.$userProfile) { (userProfile: Profile) in UserProfile(profile: userProfile) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  105. ༷ʑͳύλʔϯͷঢ়ଶ͕ൃੜͯ͠͠·͏ %SBGU 4FUUJOHT 1SP fi MF ύλʔϯ /VMM /VMM /VMM

    ύλʔϯ /POOVMM /VMM /VMM ύλʔϯ /VMM /POOVMM /VMM ύλʔϯ /VMM /VMM /POOVMM ύλʔϯ /POOVMM /POOVMM /VMM ύλʔϯ /POOVMM /VMM /POOVMM ύλʔϯ /VMM /POOVMM /POOVMM ύλʔϯ /POOVMM /POOVMM /POOVMM Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  106. ༷ʑͳύλʔϯͷঢ়ଶ͕ൃੜͯ͠͠·͏ %SBGU 4FUUJOHT 1SP fi MF ύλʔϯ /VMM /VMM /VMM

    ύλʔϯ /POOVMM /VMM /VMM ύλʔϯ /VMM /POOVMM /VMM ύλʔϯ /VMM /VMM /POOVMM ύλʔϯ /POOVMM /POOVMM /VMM ύλʔϯ /POOVMM /VMM /POOVMM ύλʔϯ /VMM /POOVMM /POOVMM ύλʔϯ /POOVMM /POOVMM /POOVMM ༗ޮͳঢ়ଶ͸͜ΕΒͷΈ Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  107. ෳ਺ͷ Navigation ͷ࠷దͳϞσϦϯάΛߟ͑Δ // Navigation ͸ಉ࣌ʹෳ਺ൃੜ͢Δ͜ͱ͕ͳ͍ͨΊɺ΋ͬͱྑ͍ϞσϦϯά͕Ͱ͖ͦ͏ @State var draft: Post?

    @State var settings: Settings? @State var userProfile: Profile? Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  108. ෳ਺ͷ Navigation ͷ࠷దͳϞσϦϯάΛߟ͑Δ // ಉ࣌ʹෳ਺ൃੜ͠ͳ͍ = enum Λ࢖͑Δ @State var

    draft: Post? @State var settings: Settings? @State var userProfile: Profile? " enum Route { case draft(Post) case settings(Settings) case userProfile(Profile) } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  109. enum Ͱ sheet ͳͲΛදࣔ͠Α͏ͱ͢Δͱʁ struct ExampleView: View { @State private

    var route: Route? // ... .sheet( item: Binding<Post?>( get: { if case let .draft(post) = route return post } else { return nil } }, set: { post if let post = post { route = .draft(post) } } ) ) { post in /* ... */ } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  110. enum Ͱ sheet ͳͲΛදࣔ͠Α͏ͱ͢Δͱʁ struct ExampleView: View { @State private

    var route: Route? // ... .sheet( item: Binding<Post?>( get: { if case let .draft(post) = route return post } else { return nil } }, set: { post if let post = post { route = .draft(post) } } ) ) { post in /* ... */ } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  111. enum Ͱ sheet ͳͲΛදࣔ͠Α͏ͱ͢Δͱʁ struct ExampleView: View { @State private

    var route: Route? // ... .sheet( item: Binding<Post?>( get: { if case let .draft(post) = route return post } else { return nil } }, set: { post if let post = post { route = .draft(post) } } ) ) { post in /* ... */ } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  112. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ struct ExampleView: View { @State

    private var route: Route? // ... .sheet( unwrapping: $route, case: ???Route.draft??? ) { $post in // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  113. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ struct ExampleView: View { @State

    private var route: Route? // ... .sheet( unwrapping: $route, // enum ࣗମΛ౉͢ (Binding value) case: ???Route.draft??? ) { $post in // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  114. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ struct ExampleView: View { @State

    private var route: Route? // ... .sheet( unwrapping: $route, case: ???Route.draft??? // ԿΒ͔ͷܗͰ enum ͷಛఆͷ case Λࢦఆ͢Δ ) { $post in // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  115. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ struct ExampleView: View { @State

    private var route: Route? // ... .sheet( unwrapping: $route, case: ???Route.draft??? ) { $post in // Associated value Λ binding value Ͱ౉ͤΔͱͳ͓ྑ͍ // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  116. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Content> { func sheet(

    unwrapping: ???, // enum ͷ binding case: ???, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  117. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Content> { func sheet(

    unwrapping: ???, // enum ͷ binding case: ???, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  118. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Content> { func

    sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: ???, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  119. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Content> { func

    sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: ???, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  120. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Case, Content> {

    func sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: CasePath<Enum, Case>, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  121. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Case, Content> {

    func sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: CasePath<Enum, Case>, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads [CasePaths] • https://github.com/pointfreeco/swift-case-paths • struct ʹ͓͚Δ Key Paths ͷ enum ൛ͷΑ͏ͳ΋ͷ • Key Paths ͸ `\User.id` ͱ͢Δ͕ɺCase Paths ͸ `/Kind.animal` • Enum ͔Βʮಛఆͷ Case ͷநग़ʯɾʮಛఆͷ Case ΁ͷ Associated value ͷ
 ຒΊࠐΈʯΛ͍ͨ͠༻్Ͱར༻͍ͯ͠Δ
  122. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Case, Content> {

    func sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: CasePath<Enum, Case>, // enum ͷಛఆͷ case @ViewBuilder content: @escaping (Binding<???>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  123. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View<Enum, Case, Content> {

    func sheet( unwrapping: Binding<Enum?>, // enum ͷ binding case: CasePath<Enum, Case>, // enum ͷಛఆͷ case // AssociatedValue ͕͋Ε͹ͦΕΛར༻Ͱ͖Δ (ͳ͚Ε͹ Void) Binding @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { // ... } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  124. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: ??? ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  125. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: ??? ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  126. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  127. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads case(casePath) ͸ Case Paths Λར༻ͨ͠ function Binding<Enum?> ͔Β Binding<Case?> Λநग़͢Δ
  128. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads `enum`.case(casePath) " Binding<Case?> case(casePath) ͸ Case Paths Λར༻ͨ͠ function Binding<Enum?> ͔Β Binding<Case?> Λநग़͢Δ
  129. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads `enum`.case(casePath) " Binding<Case?> `enum`.case(casePath) .isPresented() " Binding<Bool> case(casePath) ͸ Case Paths Λར༻ͨ͠ function Binding<Enum?> ͔Β Binding<Case?> Λநग़͢Δ
  130. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { ??? } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  131. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { Binding( unwrapping: `enum`.case(casePath) ).map(content) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  132. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { Binding( unwrapping: `enum`.case(casePath) ).map(content) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads `enum`.case(casePath) " Binding<Case?>
  133. enum Ͱ΋ѻ͍΍͍͢ sheet API Λߟ͑Δ extension View { func sheet<Enum,

    Case, Content>( unwrapping enum: Binding<Enum?>, case casePath: CasePath<Enum, Case>, @ViewBuilder content: @escaping (Binding<Case>) -> Content ) -> some View where Content: View { self.sheet( isPresented: `enum`.case(casePath).isPresented() ) { Binding( unwrapping: `enum`.case(casePath) ).map(content) } } } Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads `enum`.case(casePath) " Binding<Case?> Binding(unwrapping:) " Binding<Case> " map
  134. Before / After struct ContentView: View { enum Route {

    // ... } @State var route: Route? var body: some View { BaseView(...) .sheet( unwrapping: $route, case: /Route.draft ) { $draft in EditPostView(post: $draft) } // ... } } struct ContentView: View { @State var draft: Post? @State var settings: Settings? @State var userProfile: Profile? var body: some View { BaseView(...) .sheet(item: self.$draft) { draft in EditPostView(post: draft) } .sheet(item: self.$settings) { settings in SettingsView(settings: settings) } .sheet(item: self.$userProfile) { userProfile in UserProfile(profile: userProfile) } } } #FGPSF "GUFS Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔ > ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ > Navigation Λ enum Ͱ؅ཧͰ͖ΔΑ͏ʹ͢Δ API overloads
  135. Navigation API ͷվળʹΑΔޮՌ • SwiftUI ͷ Navigation API ʹ͓͚Δ ՝୊Λ

    API overloads ͱ͍͏ 
 γϯϓϧͳํ๏ͰղܾͰ͖ͨ (ϥΠϒϥϦͷ࣮૷͸΋ͬͱચ࿅͞Ε͍ͯ·͢) 1. ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ 2. ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ 3. ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • Navigation API ͕ΑΓ҆શͰѻ͍΍͘͢ͳΓɺNavigation ʹؔΘΔঢ়ଶͷ؅ཧ΋ ༰қʹͳΔ Navigation API ͷ՝୊ʹͲ͏ཱͪ޲͔͏͔
  136. ·ͱΊ • SwiftUI ʹ͸༷ʑͳ Navigation API ͕͋ΓɺOS ͱڞʹܹ͍͠มԽ͕ ͋ͬͨ •

    େ͖͘ Navigation API ͸ҎԼͷ 2 छྨʹ۠ผͰ͖Δ • Fire and forget API • State driven API
  137. ·ͱΊ • SwiftUI ͷ Navigation API ʹ͸ҎԼͷΑ͏ͳ՝୊͕͋ΓɺAPI Λద੾ʹ overload ͯ͠ղܾ͢Δ

    
 ʮswiftui-navigationʯͷΑ͏ͳΞϓϩʔν΋ଘࡏ͍ͯ͠Δ • ભҠઌͷը໘ʹ Binding value Λ౉͢ػߏΛඋ͍͑ͯͳ͍ • ঢ়ଶ؅ཧΛෳࡶʹͤ͞Δ API ͕ଘࡏ͍ͯ͠Δ • ෳ਺ͷ Navigation Λ؅ཧͩ͢͠ͱແବͳঢ়ଶ͕૿͑Δ • SwiftUI ͷ Navigation Λਖ਼͘͠ཧղͯ͠؅ཧ͢Ε͹৭ʑͳԸܙ͕͋Δ • Navigation ʹؔΘΔঢ়ଶ؅ཧʹ೰·͞Εͳ͍ • Deep Link ͕༰қʹͳΔɾXcode Previews ΋׆༻͠΍͘͢ͳΔ
  138. ࢀߟ • https://www.pointfree.co/collections/swiftui/navigation • https://gist.github.com/mbrandonw/f8b94957031160336cac6898a919cbb7 • https://github.com/pointfreeco/swift-composable-architecture/discussions/1140 • https://developer.apple.com/documentation/swiftui •

    https://github.com/pointfreeco/swiftui-navigation • https://swiftwithmajid.com/2022/06/15/mastering-navigationstack-in-swiftui-navigator- pattern/ • https://swiftwithmajid.com/2022/06/21/mastering-navigationstack-in-swiftui-deep- linking/