Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Navigation seems to only work once #220

Open
1 task done
Tyler-Keith-Thompson opened this issue Nov 24, 2022 · 1 comment · May be fixed by #221
Open
1 task done

[Bug]: Navigation seems to only work once #220

Tyler-Keith-Thompson opened this issue Nov 24, 2022 · 1 comment · May be fixed by #221
Labels
bug Something isn't working

Comments

@Tyler-Keith-Thompson
Copy link
Collaborator

What happened?

I think this is entirely related to a known SwiftUI bug and the deprecation of NavLinks with isActive bindings. Effectively, isActive never gets set to false. You can confirm this by adding an onChange modifier and pressing the built in "back" button. Because it never gets set to false, setting it to true triggers no changes.

Version

iOS 16

Relevant code sample

// Here's a reproducible example:

import SwiftUI
import Combine

struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                Combiner(current: Screen1(), next: Combiner(current: Screen2(), next: Combiner(current: Screen3())))
            }
        }
        .padding()
    }
}

protocol FlowRepresentableView: View { }

extension Never: FlowRepresentableView { }

class Workflow: ObservableObject {
    let proceedPublisher = PassthroughSubject<Void, Never>()
}

struct Combiner<Current: FlowRepresentableView, Next: FlowRepresentableView>: FlowRepresentableView {
    @State var current: Current
    @State var next: Next?
    @State var isActive: Bool = false
    @StateObject var workflow = Workflow()

    init(current: Current, next: Next) {
        _current = State(wrappedValue: current)
        _next = State(wrappedValue: next)
    }

    init(current: Current) where Next == Never {
        _current = State(wrappedValue: current)
        _next = State(wrappedValue: nil)
    }

    var body: some View {
        Group {
            if let next {
                NavigationLink(destination: next, isActive: $isActive) { }
                    .isDetailLink(false)
            }
            current
        }
        .onReceive(workflow.proceedPublisher) {
            isActive = true
        }
        .environmentObject(workflow)
    }
}

struct Screen1: FlowRepresentableView {
    @EnvironmentObject var workflow: Workflow
    var body: some View {
        Text("\(String(describing: Self.self))")
            .onTapGesture {
                workflow.proceedPublisher.send()
            }
    }
}

struct Screen2: FlowRepresentableView {
    @EnvironmentObject var workflow: Workflow
    var body: some View {
        Text("\(String(describing: Self.self))")
            .onTapGesture {
                workflow.proceedPublisher.send()
            }
    }
}

struct Screen3: FlowRepresentableView {
    @EnvironmentObject var workflow: Workflow
    var body: some View {
        Text("\(String(describing: Self.self))")
            .onTapGesture {
                workflow.proceedPublisher.send()
            }
    }
}


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

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Tyler-Keith-Thompson Tyler-Keith-Thompson added the bug Something isn't working label Nov 24, 2022
@Tyler-Keith-Thompson
Copy link
Collaborator Author

Note: Using the new:

        .navigationDestination(isPresented: $isActive, destination: {
            next
        })

syntax does work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant