SwiftUI发送按钮点击到子视图

时间:2020-01-15 18:22:59

标签: ios swift swiftui

我有一些视图包含相同的按钮,但内容有所不同。因此,我制作了一个ContainerView,用于容纳共享的Button布局,并为通用ContentView提供了空间。

我希望ContentView在点击ContainerView按钮时作出响应。

使用UIKit,我将在ContentView中保留对ContainerView的引用,并在按下按钮时在其上调用一个函数。但是,由于SwiftUI将所有视图都作为结构,因此将contentView放入ContainerView的{​​{1}}中时将被复制。因此,引用和显示的body是不同的,并且我无法向子视图发送消息。

代码:

ContentView

问题是:轻按struct ContainerView: View { let contentView = ContentView() var body: some View { Group { /// When this button is tapped, I would like to send a message to the `ContentView`. Button(action: self.reset, label: { Text("RESET") }) /// Unfortunately, this seemes to send a copy of the `contentView`. So I am unable to send the /// corrent struct a message. /// /// How can I send a subview a message from the superview? self.contentView } } func reset() { self.contentView.reset() } } struct ContentView: View { @State private var count: Int = 0 var body: some View { Group { Text("Count: \(self.count)") Button(action: self.increment, label: { Text("Increment") }) } } func increment() { self.count += 1 } /// When this is called from the `ContainerView`, it is accessing a different ContentView /// struct than is being displayed. func reset() { self.count = 0 } } 中的按钮后,如何发送消息并运行ContentView中的某些代码?

1 个答案:

答案 0 :(得分:4)

为什么不尝试存储对子视图的引用,为什么不在它们之间进行绑定?在您的示例中,这可以通过绑定计数来实现。

struct ContainerView: View {
    @State private var count = 0

    var body: some View {
        // Your Button wrapping the ContentView
        ContentView(count: $count)
    }

    func reset() {
        self.count = 0
    }
}


struct ContentView: View {
    @Binding var count: Int

    // ContentView's body
}

ContainerView重设计数时,绑定将更新子级。

编辑:我看到您关于要ContentView控制复位逻辑的评论。尝试复制诸如NavigationLink之类的某些功能,该功能在导航时由系统设置isActive: bool,然后重置?

根据您的情况,您可以尝试以下操作:

struct ContainerView: View {
    @State private var shouldReset: Bool = false

    var body: some View {
        // Your Button wrapping the ContentView
        ContentView(shouldReset: $shouldReset)
    }

    func reset() {
        self.shouldReset = true
    }
}


struct ContentView: View {
    @Binding var shouldReset: Bool {
        didSet {
            if shouldReset {
                // Call your reset logic here
            }
            shouldReset = false
        }
    }

    // ContentView's body
}

您的ContentView将知道更改,我们将其视为单独的“状态”,然后在操作完成后重置该状态。

这可能不是理想的解决方案,但对我来说,它似乎复制了一些第一方SwiftUI组件显示的模式。