有一个和演员一起做的模特. ButtonView更改模型中的变量. 根据模型变量值的不同,ColorView显示的 colored颜色 会有所不同.

但这个例子行不通. 因为await keyword不能在视图修改器中使用.

这个问题能解决吗? 我遗漏了什么?

感谢您的阅读.

actor ActorModel: ObservableObject {
    static let shared = ActorModel()
    private init() {}
    
    @Published var isActive: Bool = false
    
    func toggleActive() {
        isActive.toggle()
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            ColorView()
            ButtonView()
        }
        .padding()
    }
}

struct ColorView: View {
    @ObservedObject private var model = ActorModel.shared
    
    var body: some View {
        VStack {
            Rectangle()
                .foregroundStyle(await model.isActive ? .red : .blue) // <-- Problem!
                .frame(width: 100, height: 100)
        }
        .padding()
    }
}

struct ButtonView: View {
    @ObservedObject private var model = ActorModel.shared
    
    var body: some View {
        VStack {
            Button("Toggle Color") {
                Task {
                    await model.toggleActive()
                }
            }
        }
        .padding()
    }
}

推荐答案

如果你必须使用actor,那么你应该这样做:

struct ColorView: View {
    @ObservedObject private var model = ActorModel.shared

    @State private var color: Color = .gray //Default
    
    var body: some View {
        VStack {
            Rectangle()
                .foregroundStyle(color) // <-- Problem!
                .frame(width: 100, height: 100)
        }
        .padding()
        .onAppear {
            Task {
                color = await model.isActive ? .red : .blue
            }
        }
    }
}

不过,@Published属性在这里没有意义.因为你不会从anctor那里得到更新.

如果你需要订阅更新,那么你可以try 另一种方法:

struct ColorView: View {
    @ObservedObject private var model = ActorModel.shared
    @State private var isActiveState: Bool = false

    var body: some View {
        VStack {
            // ...
        }
        .onAppear {
            Task {
                await subscribeToModelChanges()
            }
        }
    }

    private func subscribeToModelChanges() async {
        await model.subscribeToIsActiveChanges { isActive in
            self.isActiveState = isActive
        }
    }
}

actor ActorModel: ObservableObject {
    // ...

    func subscribeToIsActiveChanges(_ onChange: @escaping (Bool) -> Void) async {
        // Logic to notify the subscriber about changes
        // This part is tricky because Actor doesn't have a built-in observation mechanism
        // You might need to implement your own mechanism to notify about changes
    }
}

Swift相关问答推荐

如何在SwiftUI中创建具有圆角顶部和锯齿状底部边缘的自定义Shape,类似于撕破的纸?

为什么ClosedRange<;Int&>包含的速度比预期慢340万倍?

查找数组中 ** 元素 ** 的属性的最小值和最大值

为什么要在SWIFT RandomAccessCollection协议中重新定义元素类型?

文件命名&NumberForMatter+扩展名&:含义?

如何使用模型在 SwiftUI 的列表中进行搜索

无论玩家移动到视图内的哪个位置,如何使用 SpriteKit 让敌人向玩家emits 子弹?

如何隐藏集合视图中特定的单元格,以避免出现空白空间?

在 SwiftUI 中禁用 Select 器选项

是否有一个带有空初始值设定项的 Swift 类/ struct 的标准协议

在 SwiftUI 中的 ForEach 中使用 id 时如何为数组设置动画索引

如何在 Swift 中返回 Task 中定义的变量

VStack SwiftUI 中的动态内容高度

如何快速制作虚线?

关闭 UITableViewRowAction

如何在 Swift 中将 UILabel 居中?

如何在Swift中找出字母是字母数字还是数字

如何停止 NSTimer.scheduledTimerWithTimeInterval

在 Swift 中从服务器播放视频文件

Swift 中的单元测试致命错误