nathantannar4 / Transmission

Bridges UIKit presentation APIs to a SwiftUI API so you can use presentation controllers, interactive transitions and more.
BSD 2-Clause "Simplified" License
378 stars 13 forks source link

Updates on the view dismiss the current presented VC. Not ideal #15

Closed bryan1anderson closed 8 months ago

bryan1anderson commented 10 months ago

Here's a real ugly way of reproducing it easily. Click on a cell while they're on screen. See that the presentation is disabled after the view that presented is called.

I know this is a stupid example. I'm stuck trying to debug why this is happening in my own project. The views do NOT seem to be disappearing. In fact in my project, it is doing this when even a simple string State property is updated. One that doesn't seem to layout the actual views that use the PresentationLink.

With that said, I was able to reproduce it easily using this. I don't think it's terribly ideal to destroy a presented view if a State change removes the presenter. Which does not seem to be the case in my own project. So I'm just posting here since this is the easiest way to duplicate my actual issue

struct ContentView: View {

@State var isStatusBarHidden: Bool = false
@State var statusBarStyle: StatusBarStyle = .default
@State var isHeroPresented: Bool = false
@State var progress = 0
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

var body: some View {
    NavigationView {
        ScrollView {
            VStack {
                Text("\(progress)")
                if progress % 2 == 0 {
                    LazyVGrid(columns: [.init(.flexible(), spacing: 12), .init(.flexible(), spacing: 12)]) {
                        ForEach(["C", "B", "A", "D", "E"], id: \.self) { user in
                            PresentationLink(transition: .heroMove) {
                                NavigationView {
                                    ProfileView(user: user)
                                        .navigationTitle("Profile")
                                }
                            } label: {
                                Image("Headshot\(user)")
                                    .resizable()
                                    .scaledToFill()
                                    .frame(width: 100, height: 100)
                                    .clipped()
                            }
                        }
                    }
                }
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .navigationTitle("Transmission")
        .prefersStatusBarHidden(isStatusBarHidden)
        .preferredStatusBarStyle(statusBarStyle.toUIKit())
    }
    .navigationViewStyle(.stack)
    .onReceive(timer, perform: { _ in
        progress += 1
    })
}
}
bryan1anderson commented 10 months ago

Just an example of what's going on in my project. Having the keyboard presented is what's killing it. Haven't been able to reproduce in a sample project https://github.com/nathantannar4/Transmission/assets/7976521/3ff7c6c3-d374-4eef-b361-3cb287cca565

bryan1anderson commented 10 months ago

I was able to figure out how to solve this internally by removing use of generic views. I still have no idea what was causing it but Self._printChanges() was hinting that essentially the generic was too complex and perhaps changing signatures between reloads.

nathantannar4 commented 10 months ago

It is expected that with the sample code above the presented view be dismissed, since on the state change the PresentationLink is destroyed or created.

I'd have to see a more similar example to your project to understand what's going on for you.

Having the keyboard presented is what's killing it

Are you saying that without the keyboard presented the issue does not reproduce?

Also, what transition are you using?