swift 对子视图调用视图修改函数

hmtdttj4  于 2022-12-10  发布在  Swift
关注(0)|答案(1)|浏览(181)

我有一个视图,它有一个函数fadeInOut(),可以淡入淡出一个正方形。

struct FadingSquare: View {
    
    @State var fading = false
    
    var body: some View {
        Rectangle()
            .frame(width: 20, height: 20)
            .foregroundColor(.primary)
            .opacity(fading ? 1 : 0)
            .onAppear {
                fadeInOut()
            }
    }
 
    func fadeInOut() {
        withAnimation(.linear(duration: 1)) {
            self.fading = true
        }
        withAnimation(.linear(duration: 1).delay(1)) {
            self.fading = false
        }
    }
    
}

效果很好,方块淡入,然后淡出。
但是我想把FadingSquare放在其他地方,并从父视图中调用fadingSquare.fadeInOut()

struct ContentView: View {
    
    var fadingSquare = FadingSquare()
    
    var body: some View {
        VStack {
            fadingSquare
            Button {
                fadingSquare.fadeInOut()
            } label: {
                Text("Fade")
            }

        }
    }
}

这是行不通的,把fadingSquare变成@State也是行不通的。我宁愿不使用Binding,我希望FadingSquare对它自己的值负责。

2izufjch

2izufjch1#

因此,在SwiftUI中,父母可以通过两种方式修改他们的孩子。
1.在父视图中,(ContentView)添加一个@State变量来跟踪淡入淡出。在子视图中,(FadingSquare)将@State变量更改为@Binding并删除默认值。当父级的fade变量发生变化时,您可以通过将其写入主体中的FadingSquare(fading: $ourFadingState)来更新square,其中ourFadingState是我们创建的@State变量。
1.父对象和子对象都拥有对同一个ObservableObject的引用。这是处理复杂用户界面时最有效的方法。在父对象的button操作中,您可以修改对象的fading属性。在FadingSquare中,您可以使用一个@ObservedObject变量,该变量会使正方形在发生任何更改时自动更新,无论这些更改是否在视图本身中进行。父母或在月球上。
顺便说一句,为了SwiftUI正常工作,您不需要保留fadingView属性,而是在主体代码中示例化一个全新的属性,这是因为当它是一个属性时,只有在父属性被删除后才能更新,这永远不会发生,因为ContentView通常是场景的根视图,永远不会被破坏。查看系统SwiftUI视图,注意到您没有“也不需要用变量来保存它们,我们用同样的方法。
所以改为:

var fadingSquare = FadingSquare()

var body: some View {
    fadingSquare
}

它应该是:

var body: some View {
    FadingSquare()
}

请记住,与UIKit不同,SwiftUI视图结构体不是视图本身。它是一个数据集合,* 向系统描述在给定的刷新过程中视图应该包含什么 ,就像HTML一样。因此,在主体代码中初始化一个新的FadingSquare()是正确的, 它将是同一个视图 *,即使它在代码中是“一个新的”结构体。

相关问题