5
votes

When using NavigationLink or presentation link in swiftUI, the navigation controller doesn't push or present a new View, getting error

"[WindowServer] display_timer_callback: unexpected state"

ForEach(self.items.identified(by: \.name)) {  item in


    NavigationLink(destination: Text("DT In the House")) {
        CategoryItem(item: item)


    }
}

[] nw_connection_receive_internal_block_invoke [C4] Receive reply failed with error "Operation canceled"

3
You re missing several key details that may help us. What beta version of Xcode? How about targeted OS? Maybe some more code so that we could duplicate your issue? Finally, what exactly are you trying to do? I'd usually expect a struct to be the destination - but sure, I guess a Text could work - but what about CategoryItem? Or name? Or even items? My thought is this... cut out much of your code and get something working. It looks like you are trying too... use a List(?) and navigate to a detail view from it? From what you've posted it's really hard to say....dfd
@mohitkejriwal comments, I don't have enough reputation points to comment, but do check out this ANSWER demonstrating clear way of using NavigationLink. Thanks, hope it helps someone.dbc

3 Answers

3
votes

I believe this is bug in PresentationLink in current SwiftUI beta. I get the same error while trying to reopen modal after dismissing it.

EDIT1: NavigationLink requires to be embedded in NavigationView and if there is none will present message [WindowServer] display_timer_callback: unexpected state (now:1abc3d3ccc7 < expected:1abc3d91a0f)

EDIT2: PresentationLink only appears to be buggy while embedded in things like NavigationBarItems or Lists etc.

3
votes

It seems to be a bug. I've managed to whip up a (dirty) workaround:

private enum SetPresentedViewKey: EnvironmentKey {
    static var defaultValue: (AnyView?) -> () {
        fatalError()
    }
}

private extension EnvironmentValues {
    var setPresentedView: (AnyView?) -> () {
        get {
            self[SetPresentedViewKey.self]
        } set {
            self[SetPresentedViewKey.self] = newValue
        }
    }
}

/// A replacement for the buggy (as of Xcode 11 b3) `PresentationLink`.
public struct PresentationLink2<Destination: View, Label: View>: View {
    public let destination: Destination
    public let label: Label

    @Environment(\.setPresentedView) private var setPresentedView
    @State private var presentedView: AnyView? = nil

    public init(destination: Destination, @ViewBuilder _ label: () -> Label) {
        self.destination = destination
        self.label = label()
    }

    private struct _Body<Destination: View, Label: View>: View {
        @Environment(\.setPresentedView) private var setPresentedView

        let destination: Destination
        let label: Label

        init(destination: Destination, label: Label) {
            self.destination = destination
            self.label = label
        }

        var body: some View {
            Button(action: present, label: { label })
        }

        func present() {
            setPresentedView(AnyView(destination))
        }
    }

    public var body: some View {
        _Body(destination: destination, label: label)
            .environment(\.setPresentedView, { self.presentedView = $0 })
            .presentation(presentedView.map {
                Modal($0, onDismiss: { self.presentedView = nil })
            })
    }
}

Just copy the code above into your codebase and use PresentationLink2 instead of PresentationLink.


As noted by @kozlowsqi, PresentationLink seems to be broken when embedded in a NavigationView. What's alarming is that it's still broken as of Xcode beta 3.

Edit: I've filed a radar through the new Feedback Assistant app, FB6525020. Please raise your own and reference mine, and hopefully this will be resolved by beta 4.

1
votes

I've created a PresentationLink replacement that works far more reliable. Hopefully it won't be needed anymore as soon as beta 4 is released.

You can find a gist here: https://gist.github.com/petercv/3fba967a69b262901053fc8638b7851b

I've also added support for a .isModalInPresentation(_ value: Bool) modifier to set the isModalInPresentation property of UIViewController. Hopefully Apple will add this too soon.