sash
sash

Reputation: 8715

SwiftUI sheet gets dismissed the first time it is presented

This bug is driving me insane. Sometimes (well most of the time) presented sheet gets dismissed first time it is opened. This is happening only on a device and only the first time the app is launched. Here is how it looks on iPhone 11 running iOS 14.1 built using Xcode 12.1 (can be reproduced on iPhone 7 Plus running iOS 14.0.1 as well):

enter image description here

Steps in the video:

  1. I open app
  2. Swiftly navigate to Details view
  3. Open Sheet
  4. Red Sheed gets dismissed by the system???
  5. I open sheet again and it remains on the screen as expected.

This is SwitUI App project (using UIKIt App Delegate) and deployment iOS 14. Code:

struct ContentView: View {
   
    var body: some View { 
        NavigationView {
            NavigationLink(destination: DetailsView()) {
                Text("Open Details View")
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct DetailsView: View {
   
    @State var sheetIsPresented: Bool = false
 
    var body: some View {
        VStack {
            Button("Open") {
                sheetIsPresented.toggle()
            }
        }.sheet(isPresented: $sheetIsPresented, content: {
            SheetView()
        })
    }
}

struct SheetView: View {
   
    var body: some View {
        Color.red
    }
}

I was able to fix this problem by removing line .navigationViewStyle(StackNavigationViewStyle()), but I need StackNavigationViewStyle in my project. Any help will be appreciated.

Updated: There is a similar post on Apple forum with sheet view acting randomly weird. One solution that I found is to move sheet to the root view outside NavigationLink (that would be ContentView in my example), but that is not ideal solution.

Upvotes: 9

Views: 2613

Answers (2)

Kavindu Dissanayake
Kavindu Dissanayake

Reputation: 883

Just add your NavigationView view to bellow code line

.navigationViewStyle(StackNavigationViewStyle())

Example:


NavigationView {

}
.navigationViewStyle(StackNavigationViewStyle())

Problem will be solved (same issues I was faced)

Upvotes: 0

Yrb
Yrb

Reputation: 9675

I had the same problem in an app. After a great deal of research, I found that making the variable an observed object fixed the problem in SwiftUI 1, and it seems to be in SwiftUI 2. I do remember that it was an intermittent problem on an actual device, but it always happened in the simulator. I wish I could remember why, maybe when the sheet appears it resets the bound variable?, but this code fixes the problem:

import SwiftUI
import Combine

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailsView()) {
                Text("Open Details View")
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct DetailsView: View {
   
    @ObservedObject var sheetIsPresented = SheetIsPresented.shared
    
    var body: some View {
        VStack {
            Button("Open") {
                sheetIsPresented.value.toggle()
            }
        }.sheet(isPresented: $sheetIsPresented.value, content: {
            SheetView()
        })
    }
}

struct SheetView: View {
   
    var body: some View {
        Color.red
    }
}

final class SheetIsPresented: NSObject, ObservableObject {
    let objectWillChange = PassthroughSubject<Void, Never>()
    
    static let shared = SheetIsPresented()
    
    @Published var value: Bool = false {
        willSet {
            objectWillChange.send()
        }
    }
    
}


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

Tested on Xcode 12.1, iOS 14.1 in simulator.

Upvotes: 4

Related Questions