使用@ObservableObject时,SwiftUI NavigationLink推入onAppear会立即弹出视图 [英] SwiftUI NavigationLink push in onAppear immediately pops the view when using @ObservableObject

查看:204
本文介绍了使用@ObservableObject时,SwiftUI NavigationLink推入onAppear会立即弹出视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望以编程方式能够在视图出现时导航到NavigationLinksList内的链接(通过推送通知构建深层链接).我有一个字符串-> Bool字典,该字典绑定到我的视图内的自定义Binding<Bool>.当视图出现时,我设置了bool属性,导航发生,但是,它立即弹出.我按照 SwiftUI导航链接的答案立即向后导航,并确保List具有唯一的标识符,但是问题仍然存在.

I want to programmatically be able to navigate to a link within a List of NavigationLinks when the view appears (building deep linking from push notification). I have a string -> Bool dictionary which is bound to a custom Binding<Bool> inside my view. When the view appears, I set the bool property, navigation happens, however, it immediately pops back. I followed the answer in SwiftUI NavigationLink immediately navigates back and made sure that each item in the List has a unique identifier, but the issue still persists.

两个问题:

  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")
                }
            }
        }
    }
}

推荐答案

该错误是由于ViewModel的生命周期引起的,目前是SwiftUI NavigationLink本身的一个限制,必须等待苹果是否更新了该版本.下一个版本中有待解决的问题.

The error is due to the lifecycle of the ViewModel, and is a limitation with SwiftUI NavigationLink itself at the moment, will have to wait to see if Apple updates the pending issues in the next release.

SwiftUI 2.0的更新:

Update for SwiftUI 2.0:

更改:

@ObservedObject var contentViewModel = ContentViewModel()

收件人:

@StateObject var contentViewModel = ContentViewModel()

@StateObject表示视图模型状态的更改不会触发整个body的重绘.

@StateObject means that changes in the state of the view model do not trigger a redraw of the whole body.

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

You also need to store the shouldPushPage3 variable outside the View as the view will get recreated every time you pop back to the root 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的Beta版-它将在下一个GM Xcode版本中启用约一个月.

The bug got fixed with the latest SwiftUI release. But to use this code at the moment, you will need to use the beta version of Xcode and iOS 14 - it will be live in a month or so with the next GM Xcode release.

这篇关于使用@ObservableObject时,SwiftUI NavigationLink推入onAppear会立即弹出视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆