【问题标题】:SwiftUI NavigationView pops by itselfSwiftUI NavigationView 自行弹出
【发布时间】:2020-08-12 22:09:36
【问题描述】:

这是一个非常奇怪的问题,因为我无法在孤立的代码中重现,但我希望有人可以考虑一下原因。我有一个视图,假设 ContentView 的 ContentViewModel 是 ObservedObject,然后还有另一个 View ContentView2。我们在 ContentView 中有 NavigationView,它将导航链接包装到 ContentView2。这有点奇怪,但是当我们做一些影响 ContentViewModel 的更改时,NavigationView 会弹出 ContentView2 以便我们最终进入初始 ContentView,但我们没有做任何诸如关闭 ContentView2 或点击返回按钮之类的操作。我有一个与我的项目中使用的代码相似的代码,但请注意,在此代码中一切正常:

func qrealm() -> Realm {
    return try! Realm(configuration: .init( inMemoryIdentifier: "yw"))
}

class SomeRObj: Object {
    @objc dynamic var name: String = ""
    
    convenience init(name: String) {
        self.init()
        self.name = name
    }
    
    static var instance: SomeRObj {
        return qrealm().objects(SomeRObj.self).first!
    }
}
struct SomeRObjWrapped: Hashable {
    var obj: SomeRObj
    var prop: Int
}

class ContentViewModel: ObservableObject {
    @Published var someRObj: [SomeRObjWrapped] = []
    var any: Any?
    init() {
        let token = qrealm().objects(SomeRObj.self).observe { changes in
            switch changes {
            case let .initial(data), let .update(data, deletions: _, insertions: _, modifications: _):
                let someObjs = data.map { SomeRObjWrapped(obj: $0, prop: Int.random(in: 1..<50)) }
                self.someRObj = Array(someObjs)
            default: break
            }
        }
        self.any = token
    }
}

struct ContentView: View {
    @ObservedObject var model: ContentViewModel = ContentViewModel()
    
    var body: some View {
        NavigationView {
        VStack {
            ForEach(model.someRObj, id: \.self) { obj in
                Heh(obj: obj.obj, pr: obj.prop)
            }
            NavigationLink(destination: ContentView2()) {
                Text("Link")
            }
        }
        }
    }
}

struct Heh: View {
    var obj: SomeRObj
    var pr: Int
    var body: some View {
        Text("\(obj.name) \(pr)")
    }
}

struct ContentView2: View {
    var body: some View {
        Button(action: { try! qrealm().write {
            let elem = qrealm().objects(SomeRObj.self).randomElement()
            elem?.name = "jotaro kujo"
            }
            
        }, label: { Text("Toggle") })
    }
}

【问题讨论】:

    标签: ios swift swiftui realm


    【解决方案1】:

    您可以将\.self 替换为\.id

    ForEach(model.someRObj, id: \.id) { obj in
        Heh(obj: obj.obj, pr: obj.prop)
    }
    

    然后每个对象都将由id 标识,并且ForEach 循环只会在id 更改时刷新。

    【讨论】:

    • 谢谢,它确实成功了,但我仍然想知道它为什么会发生,因为在上面的代码中,这个错误(或功能)不会重现
    • @AnonAnon 我不太清楚——它可能与我不知道的领域有关。从 SwiftUI 的角度来看,您在 ContentView2 中修改了一些对象,这些对象也显示在 ForEach 中,并且重新绘制了 ContentView。解决方案是告诉 ForEach 仅在 id 更改时重绘。
    【解决方案2】:

    感谢pawello2222,我找到了它背后的真正原因。我的列表中有一个 NavigationLink,因此每次发生更改时都会重新绘制 NavigationLink 并刷新它的状态。我希望它对某人有所帮助,而pawello2222之前写的解决方案是通过id参数识别视图。

    【讨论】:

      猜你喜欢
      • 2022-11-21
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2021-01-15
      • 2021-07-22
      • 1970-01-01
      相关资源
      最近更新 更多