【问题标题】:SwiftUI NavigationLink push in onAppear immediately pops the view when using @ObservableObjectSwiftUI NavigationLink push in onAppear 使用@ObservableObject 时立即弹出视图
【发布时间】:2020-09-28 05:04:28
【问题描述】:

当视图出现时,我希望能够以编程方式导航到 List 或 NavigationLinks 中的链接(从推送通知构建深层链接)。我有一个字符串 -> Bool 字典,它绑定到我的视图中的自定义 Binding<Bool>。当视图出现时,我设置 bool 属性,导航发生,但是,它立即弹回。我遵循SwiftUI NavigationLink immediately navigates back 中的答案并确保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")
                }
            }
        }
    }
}

【问题讨论】:

标签: ios swift swiftui-navigationlink swiftui


【解决方案1】:

该错误是由于 ViewModel 的生命周期引起的,并且目前是 SwiftUI NavigationLink 本身的限制,将不得不等待 Apple 是否在下一个版本中更新未决问题。

SwiftUI 2.0 的更新:

变化:

@ObservedObject var contentViewModel = ContentViewModel()

到:

@StateObject var contentViewModel = ContentViewModel()

@StateObject表示视图模型状态的变化不会触发整个body的重绘。

您还需要将shouldPushPage3 变量存储在View 之外,因为每次弹回根View 时都会重新创建视图。

enum DeepLinking {
    static var shouldPushPage3 = true
}

并引用如下:

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

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

【讨论】:

  • 感谢您如此迅速地跟进。
  • 不用担心。如果您测试后有任何问题,请告诉我!
  • 我在这上面浪费了很多时间,最终不得不杀死所有UINavigationView 和UINavigationLink 并替换为UINavigationController。再也不会UINavigationView 直到一年后,努力不值得结果,人们采用 14.0 需要时间?
  • 除非你是 Apple,否则它还没有真正准备好用于生产代码
  • 在按钮上单击从视图模型向数组添加项目,视图立即弹出。知道为什么会这样吗?
【解决方案2】:

我遇到了这个问题,使用标准(不使用'isActive')NavigationLink - 对我来说,问题原来是视图修饰符的使用:.onAppear{code} 和 .onDisappear{code} 在目标视图中。我认为它导致了重新绘制循环或导致视图弹回我的列表视图(大约 1 秒后)。 我通过将修饰符移动到不受这些修饰符中的代码影响的目标视图的一部分来解决它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2019-11-23
    • 1970-01-01
    • 2019-12-26
    • 2020-04-27
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多