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

SwiftUI Navigation のすべて

Aikawa
September 10, 2022

SwiftUI Navigation のすべて

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

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/