首页 > 解决方案 > 具有基于字典的自定义绑定的 SwiftUI NavigationLink 在转换回来后无法重置

问题描述

我有一个存储 string -> bool 的字典,在我看来,我将这个字典包装在 a 周围Binding<Bool>以便能够存储每个状态,NavigationLink以便以后能够以编程方式导航。现在,这是第一次,第 1 页 -> 第 2 页 -> 第 3 页,但是当您返回第 2 页时,导航停止工作。

我已经检查了字典的值在被点击isLinkActive时确实得到了正确的更新,但是没有被激活。NavigationLinkNavigationLink

import SwiftUI

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

struct ContentView: View {

    @ObservedObject var contentViewModel = ContentViewModel()

    var page3: some View {
        Text("Page 3")
    }

    @State var data = ["1", "2", "3"]

    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 page2: some View {
        return
            List(data, id: \.self) { data in
                NavigationLink(destination: self.page3, isActive: self.binding(chatId: data)) {
                    Text("Page \(data) Link")
                }
        }
    }

    var body: some View {
        return NavigationView() {
            VStack {
                Text("Page 1")
                NavigationLink(destination: page2) {
                    Text("Page 2 Link")
                }
            }
        }
    }
}

标签: swiftswiftuiswift5swiftui-navigationlink

解决方案


您的代码逻辑没有任何问题。唯一的问题是 SwiftUI不会重绘page2,因为它只会在var body期间重绘onAppear,而且这个视图不在上下文中。因此,强制刷新的方法是使page2body 变量。

struct ContentView: View {

    var body: some View {
        return NavigationView() {
            VStack {
                Text("Page 1")
                NavigationLink(destination: ContentViewTwo()) {
                    Text("Page 2 Link")
                }
            }
        }
    }
}

struct ContentViewTwo: View {

  @ObservedObject var contentViewModel = ContentViewModel()

  var page3: some View {
      Text("Page 3")
  }

  @State var data = ["1", "2", "3"]

  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 \(data) Link")
              }
      }
  }
}

推荐阅读