gpt4 book ai didi

SwiftUI - 通过嵌套引用类型传播更改通知

转载 作者:行者123 更新时间:2023-12-03 22:00:13 26 4
gpt4 key购买 nike

我想将 SwiftUI 中的 ObservableObject 行为扩展到嵌套类,我正在寻找正确的方法来做到这一点。它可以使用Combine“手动”完成,但我想使用SwiftUI有一种更简洁的方法,我希望你能指出我正确的方向。这就是我的意思……

下面是 ObservableObject 的一个典型应用,它使 View 动态响应引用类型的变化。点击按钮切换 showText值,使文本在屏幕上出现/消失:

import SwiftUI

class MyClass: ObservableObject {
@Published var showText = false
}


struct ContentView: View {

@ObservedObject var instance = MyClass()

var body: some View {
VStack(spacing: 10) {
Button(action: {
print(self.instance.showText)
self.instance.showText.toggle()
}) {
Text("BUTTON").bold().padding()
.foregroundColor(.white)
.background(Color.red)
}
if instance.showText {
Text("Hello, World!")
}
}
}
}

这工作正常。

但是下面的修改呢,其中包含 showText 的类是 InnerClass ,本身包含在 OuterClass 中?按钮切换 showText很好,但是值更改的通知不再通过 OuterClass 传播实例到 View ,因此 View 根本不再显示文本。
import SwiftUI

class OuterClass: ObservableObject {
@Published var innerInstance = InnerClass()
}

class InnerClass: ObservableObject {
@Published var showText = false
}

struct ContentView: View {

@ObservedObject var outerInstance = OuterClass()

var body: some View {
VStack(spacing: 10) {
Button(action: {
self.outerInstance.innerInstance.showText.toggle()
}) {
Text("BUTTON").bold().padding()
.foregroundColor(.white)
.background(Color.red)
}
if outerInstance.innerInstance.showText {
Text("Hello, World!")
}
}
}
}

什么是优雅的解决方法?

最佳答案

它可以在你的模型中完成

import Combine // required for AnyCancelable

class OuterClass: ObservableObject {
private let _inner: InnerClass
var innerInstance: InnerClass {
return _inner
}
var store = Set<AnyCancellable>()
init(_ inner: InnerClass) {
_inner = inner
inner.$showText.sink { [weak self] _ in
self?.objectWillChange.send()
}.store(in: &store)
}
}

以及如何在您的示例中使用
import SwiftUI
import Combine

class OuterClass: ObservableObject {
private let _inner: InnerClass
var innerInstance: InnerClass {
return _inner
}
var store = Set<AnyCancellable>()
init(_ inner: InnerClass) {
_inner = inner
inner.$showText.sink { [weak self] _ in
self?.objectWillChange.send()
}.store(in: &store)
}
}

class InnerClass: ObservableObject {
@Published var showText = false
}

let inner = InnerClass()
let outer = OuterClass(inner)

struct ContentView: View {

@ObservedObject var outerInstance = outer

var body: some View {
VStack(spacing: 10) {
Button(action: {
self.outerInstance.innerInstance.showText.toggle()
}) {
Text("BUTTON").bold().padding()
.foregroundColor(.white)
.background(Color.red)
}
if outerInstance.innerInstance.showText {
Text("Hello, World!")
}
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

如果你喜欢 观察你内在对象的任何变化 , 去做就对了!
class OuterClass: ObservableObject {
private let _inner: InnerClass
var innerInstance: InnerClass {
return _inner
}
var store = Set<AnyCancellable>()
init(_ inner: InnerClass) {
_inner = inner
inner.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}.store(in: &store)
}
}

更新:基于下面的讨论
class OuterClass: Combine.ObservableObject {
private let _inner: InnerClass
var innerInstance: InnerClass {
return _inner
}
var store = Set<AnyCancellable>()
init(_ inner: InnerClass) {
_inner = inner
inner.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}.store(in: &store)
}
}

关于SwiftUI - 通过嵌套引用类型传播更改通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60119057/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com