0

Updating a project to swiftUI 2.0 on iOS 14 and presenting a modal view seems broken. The modal view appears empty.

Here is the code I use and the example project I created to illustrate this : https://github.com/Esowes/testModal

The ContentView :

import SwiftUI
import CoreData

struct ContentView: View {
    
    @State var modalIsPresented = false // The "settingsView" modally presented as a sheet
        
   @State private var modalViewCaller = 0 // This triggers the appropriate modal (only one in this example)

    
    var body: some View {
        
        NavigationView {
            VStack {
                Spacer()
                Button(action: {
                    self.modalViewCaller = 1 // SettingsView
                    self.modalIsPresented = true
                }
                    ) {
                        Text("Tap to present Modal")
                     }
                Spacer()
            } // END of main VStack
            .onAppear() {
                self.modalViewCaller = 0
            }
            .navigationBarTitle("Test app", displayMode: .inline)
        } // END of NavigationView
        .sheet(isPresented: $modalIsPresented, content: sheetContent)
        .navigationViewStyle(StackNavigationViewStyle()) // This avoids dual column on iPad

    } // END of var body: some View
  // MARK: @ViewBuilder func sheetContent() :
    
    @ViewBuilder func sheetContent() -> some View {
        
        if modalViewCaller == 1 {
            SettingsView()
                .navigationViewStyle(StackNavigationViewStyle())
                .onDisappear { // This always triggered
                    print("onDissappear triggered ! at \(Date().debugDescription)")
                    self.modalViewCaller = 0
                }
            }
    } // END of func sheetContent
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        return ContentView()
        
    }
}

If anyone has ideas, I would greatly appreciate it, as my search so far has yielded nothing...

Thanks

Esowes
  • 287
  • 2
  • 13

1 Answers1

1

Possible solution is to separate content of sheet into dedicated sub-view, like below.

Tested with Xcode 12.1 / iOS 14.1

struct ContentView: View {
    
    @State var modalIsPresented = false // The "settingsView" modally presented as a sheet
        
   @State private var modalViewCaller = 0 // This triggers the appropriate modal (only one in this example)

    
    var body: some View {
        
        NavigationView {
            VStack {
                Spacer()
                Button(action: {
                    self.modalViewCaller = 1 // SettingsView
                    self.modalIsPresented = true
                }
                    ) {
                        Text("Tap to present Modal")
                     }
                Spacer()
            } // END of main VStack
            .onAppear() {
                self.modalViewCaller = 0
            }
            .navigationBarTitle("Test app", displayMode: .inline)
        } // END of NavigationView
        .sheet(isPresented: $modalIsPresented) {
            SheetContent(modalViewCaller: $modalViewCaller)     // << here !!
        }
        .navigationViewStyle(StackNavigationViewStyle()) // This avoids dual column on iPad

    } // END of var body: some View
  // MARK: @ViewBuilder func sheetContent() :
}

struct SheetContent: View {
    @Binding var modalViewCaller: Int
    var body: some View {
      if modalViewCaller == 1 {
            SettingsView()
                 .navigationViewStyle(StackNavigationViewStyle())
                 .onDisappear { // This always triggered
                      print("onDissappear triggered ! at \(Date().debugDescription)")
                      self.modalViewCaller = 0
                 }
            }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Many thanks Asperi, works like a charm. Any idea why the "old" way is not working anymore ? – Esowes Nov 06 '20 at 00:28