SwiftUI NavigationLink push in onAppear 使用@ObservableObject 时立即弹出视图

Zor*_*ayr 5 ios swift swiftui swiftui-navigationlink

我想以编程方式能够浏览到内的一个链接ListNavigationLinks时候出现视(深深的建设从推送通知链接)。我有一个字符串 -> Bool 字典,它绑定到Binding<Bool>我的视图中的自定义。当视图出现时,我设置了 bool 属性,导航发生,但是,它立即弹出。我按照SwiftUI NavigationLink 中的答案立即导航回并确保中的每个项目List都有唯一的标识符,但问题仍然存在。

两个问题:

  1. 我这里的绑定逻辑是否正确?
  2. 为什么视图会立即弹出?
import SwiftUI

class ContentViewModel: ObservableObject {
    @Published var isLinkActive:[String: Bool] = [:]
}

struct ContentViewTwo: View {
    @ObservedObject var contentViewModel = ContentViewModel()
    @State var data = ["1", "2", "3"]
    @State var shouldPushPage3: Bool = true

    var page3: some View {
        Text("Page 3")
            .onAppear() {
                print("Page 3 Appeared!")
        }
    }

    func binding(chatId: String) -> Binding<Bool> {
        return .init(get: { () -> Bool in
            return self.contentViewModel.isLinkActive[chatId, default: false]
        }) { (value) in
            self.contentViewModel.isLinkActive[chatId] = value
        }
    }

    var body: some View {
        return
            List(data, id: \.self) { data in
                NavigationLink(destination: self.page3, isActive: self.binding(chatId: data)) {
                    Text("Page 3 Link with Data: \(data)")
                }.onAppear() {
                    print("link appeared")
                }
            }.onAppear() {
                print ("ContentViewTwo Appeared")
                if (self.shouldPushPage3) {
                    self.shouldPushPage3 = false
                    self.contentViewModel.isLinkActive["3"] = true
                    print("Activating link to page 3")
                }
        }
    }
}

struct ContentView: View {
    var body: some View {
        return NavigationView() {
            VStack {
                Text("Page 1")
                NavigationLink(destination: ContentViewTwo()) {
                    Text("Page 2 Link")
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*tti 5

该错误是由于 ViewModel 的生命周期造成的,目前是 SwiftUI NavigationLink 本身的一个限制,必须等待 Apple 是否在下一个版本中更新未决问题。

更新SwiftUI 2.0

改变:

@ObservedObject var contentViewModel = ContentViewModel()
Run Code Online (Sandbox Code Playgroud)

到:

@StateObject var contentViewModel = ContentViewModel()
Run Code Online (Sandbox Code Playgroud)

@StateObject意味着视图模型状态的变化不会触发整个body.

您还需要将shouldPushPage3变量存储在外部,View因为每次弹出到 root 时都会重新创建视图View

enum DeepLinking {
    static var shouldPushPage3 = true
}
Run Code Online (Sandbox Code Playgroud)

并参考如下:

if (DeepLinking.shouldPushPage3) {
    DeepLinking.shouldPushPage3 = false
    self.contentViewModel.isLinkActive["3"] = true
    print("Activating link to page 3")
}
Run Code Online (Sandbox Code Playgroud)

该错误在最新的 SwiftUI 版本中得到修复。但是目前要使用此代码,您需要使用 Xcode 和 iOS 14 的测试版 - 它将在一个月左右的下一个 GM Xcode 版本中上线。