protocol: MyProtocol {
var showView: Bool { get set }
}
struct MyView: View, MyProtocol {
var showView = false
var body: some View {
ZStack(){
AnotherView(myProtocol: self)
if showView {
// code
}
}
}
}
struct AnotherView: View {
var myProtocol: MyProtocol
var body: some View {
ZStack(){
Text("Text")
.onTapGesture{
myProtocol.showView = true // xcode complains on this line
}
}
}
}
我有上面的代码,我想当Text
被点击时,showView
变量改变值,然后做我想做的任何事情
这不是我的实际代码,只是一个最小的复制示例,我不得不使用protocol
,因为AnotherView
是一个可以从多个方面使用的可重用视图,所以我只想更改当前父视图的showView
值
但是XCode
一直在抱怨,说:
无法分配给属性:"self"是不可变的
如何从子视图更改父视图协议属性的值?
1条答案
按热度按时间f0ofjuux1#
你应该检查一下你的“最小复制示例”是否产生了你描述的错误。你的示例没有,因为
MyProtocol
声明中有语法错误。正确的声明是更正该错误将导致您描述的错误。
SwiftUI视图中的可变状态需要存储在某种
DynamicProperty
中,最常见的是使用属性 Package 器@State
、@Binding
或@ObservedObject
之一。但是很难理解如何修复您的示例,因为在您的示例中,您有一个
MyView
,它将自己传递给AnotherView
,并期望AnotherView
改变传入的MyView
。这并不是SwiftUI的设计工作方式。在SwiftUI中,可变状态需要更清晰地与视图分离。也许这正好抓住了你想要达到的效果:
注意,因为
AnotherView
需要一个MyProtocol
存在,所以我必须显式地声明state
是MyView
中的一个存在(any MyProtocol
),你可以通过观看WWDC 2022: Embrace Swift generics和WWDC 2022: Design protocol interfaces in Swift来学习更多关于存在的知识。最好避免在这里使用存在式,而是将
AnotherView
设置为泛型,如下所示: