Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI Navigationlink or Presentation Link not working

Tags:

swiftui

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"

like image 911
Danny Meng Avatar asked Jul 03 '19 20:07

Danny Meng


People also ask

What is Stacknavigationviewstyle?

A navigation view style represented by a view stack that only shows a single top view at a time.

What is isDetailLink?

isDetailLink. A Boolean value that specifies whether this link presents its destination as the detail component when used in a multi-column navigation view.


3 Answers

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.

like image 152
kozlowsqi Avatar answered Oct 10 '22 15:10

kozlowsqi


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.

like image 31
Vatsal Manot Avatar answered Oct 10 '22 13:10

Vatsal Manot


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.

like image 26
Peter Verhage Avatar answered Oct 10 '22 14:10

Peter Verhage