SwiftUI 发送按钮点击到子视图
Posted
技术标签:
【中文标题】SwiftUI 发送按钮点击到子视图【英文标题】:SwiftUI send button tap to subview 【发布时间】:2020-01-15 18:22:59 【问题描述】:我有几个视图包含相同的按钮和一些不同的内容。因此,我创建了一个ContainerView
,其中包含共享的Button
布局,并为通用ContentView
留出了空间。
我希望ContentView
在点击ContainerView
按钮时做出响应。
使用 UIKit,我会在 ContainerView
中保存对 ContentView
的引用,并在按下按钮时调用它的函数。但是,因为 SwiftUI 将所有视图都作为结构体,所以 contentView
在放入 ContainerView
的 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
所以问题是:当点击ContainerView
中的按钮时,如何向ContentView
中发送消息并运行一些代码?
【问题讨论】:
在一个视图中有一个@State
属性,并将其作为@Binding
传递给另一个视图。然后,您可以更改 Binding 值的值,这将在第一个视图中更新您的 State 值。
所以问题是我希望ContentView
指示重置功能的实现,而不是ContainerView
。在此示例中,我有一个 int,但在我自己的项目中,绑定是一个具有多个属性的结构;每个不同的ContentView
都会重置一个不同的。
你尝试使用 reactive SwiftUI 到 imperative UIKit-like 方式。相反,您需要修改 model,具体取决于哪个视图应该做出相应的反应并重建自身。
@Asperi,对,我想我的问题是reactive SwiftUI
完成此任务的方式是什么。看起来有些人在下面给出了一些有用的答案!
【参考方案1】:
与其尝试存储对子视图的引用,不如在它们之间进行绑定?在您的示例中,这可以通过绑定到计数来实现。
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
重置计数时,绑定将更新孩子。
编辑:我看到您的 cmets 想要 ContentView
控制重置逻辑。如果尝试复制 NavigationLink
之类的功能,其中一个 isActive:
布尔值由系统在导航时设置然后重置?
在您的情况下,您可以尝试以下方法:
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 组件所显示的模式。
【讨论】:
啊,没想到 didSet。试图弄清楚我如何将绑定转换为执行一些代码。谢谢!以上是关于SwiftUI 发送按钮点击到子视图的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:如何在单击 ActionSheet 按钮时呈现新视图?