SwiftUI视图中设置计算属性报错,如何正确调用setter?
解决SwiftUI中计算属性Setter调用的编译器错误
我来帮你搞定这个问题~你遇到的Cannot assign to property: 'self' is immutable错误,本质原因是SwiftUI的View是值类型(struct),默认在onTapGesture这类闭包里的self是不可变的(相当于let常量),而你的计算属性s的setter会修改视图内部的@State状态,不可变的self不允许执行这种修改操作。
下面给你两种可行的解决方法:
方法一:给计算属性Setter添加mutating关键字
把计算属性的setter标记为mutating,然后在闭包里创建一个可变的视图实例来修改,最后赋值回self触发视图更新:
struct Test: View{ @State var _s = "test" @State var _s2 = true private var s : String { get { _s } // 给setter加上mutating关键字,允许修改self状态 mutating set (new) { _s = "no test" _s2 = false // 这里可以继续添加其他逻辑 } } var body: some View { Text("\(s)") .onTapGesture { // 创建可变的视图实例 var mutableView = self mutableView.s = "anything" // 将修改后的实例赋值回self,触发SwiftUI重新渲染 self = mutableView } } }
方法二:提取状态修改逻辑为独立方法(更推荐)
看你的代码,setter里并没有用到传入的new参数,只是固定修改_s和_s2,这种情况下把逻辑抽成普通方法更清晰。而且@State属性的实际存储由SwiftUI框架管理,即使self不可变,也能直接修改它们的wrappedValue:
struct Test: View{ @State var _s = "test" @State var _s2 = true // 只保留getter,或者直接用_s也可以 private var s : String { get { _s } } // 把原来setter里的逻辑提取成方法 private func updateViewState() { _s = "no test" _s2 = false // 这里可以添加其他需要执行的逻辑 } var body: some View { Text("\(s)") .onTapGesture { // 直接调用方法修改状态即可 updateViewState() } } }
如果你的setter需要用到传入的new值,方法一完全适用;如果后续状态逻辑更复杂,也可以考虑用@Binding或自定义属性包装器,但这两种简单方法已经能解决当前问题啦~
内容的提问来源于stack exchange,提问作者mica
相关产品推荐
相关产品推荐

