SwiftUI 组合:嵌套的观察对象

莱尼

让 swiftUI 仍然基于嵌套的观察对象更新的最佳方法是什么?

以下示例显示了我对嵌套观察对象的含义。ball manager 的 balls 数组是一个已发布的属性,它包含一组可观察对象,每个对象都有一个已发布的属性本身(颜色字符串)。

不幸的是,当点击其中一个球时,它不会更新球名称,也不会收到更新。所以我可能搞砸了在这种情况下如何结合工作?

import SwiftUI

class Ball: Identifiable, ObservableObject {
    let id: UUID
    @Published var color: String
    init(ofColor color: String) {
        self.id = UUID()
       self.color = color
    }
}

class BallManager: ObservableObject {
    @Published var balls: [Ball]
    init() {
        self.balls = []
    }
}

struct Arena: View {
   @StateObject var bm = BallManager()

    var body: some View {
        VStack(spacing: 20) {
            ForEach(bm.balls) { ball in
                Text(ball.color)
                    .onTapGesture {
                        changeBall(ball)
                    }
            }
        }
        .onAppear(perform: createBalls)
        .onReceive(bm.$balls, perform: {
            print("ball update: \($0)")
        })
    }
    
    func createBalls() {
        for i in 1..<4 {
            bm.balls.append(Ball(ofColor: "c\(i)"))
        }
    }
    
    func changeBall(_ ball: Ball) {
        ball.color = "cx"
    }
}
乔治_E

Ballballs数组的变化,你可以调用objectWillChange.send()更新ObservableObject

以下应该对你有用:

class BallManager: ObservableObject {
    @Published var balls: [Ball] {
        didSet { setCancellables() }
    }
    let ballPublisher = PassthroughSubject<Ball, Never>()
    private var cancellables = [AnyCancellable]()
    
    init() {
        self.balls = []
    }
    
    private func setCancellables() {
        cancellables = balls.map { ball in
            ball.objectWillChange.sink { [weak self] in
                guard let self = self else { return }
                self.objectWillChange.send()
                self.ballPublisher.send(ball)
            }
        }
    }
}

并通过以下方式获得更改:

.onReceive(bm.ballPublisher) { ball in
    print("ball update:", ball.id, ball.color)
}

注意:如果balls传入的初始值不总是一个空数组,您还应该调用setCancellables()init.d 。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章