Skip to content

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

Open
@Tyler-Keith-Thompson

Description

@Tyler-Keith-Thompson

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions