ios - SwiftUI 将按钮点击发送到 subview

标签 ios swift swiftui

我有几个包含相同按钮但内容不同的 View 。因此,我制作了一个包含共享 Button 布局的 ContainerView,并为通用 ContentView 留出了空间。

我希望 ContentViewContainerView 按钮被点击时做出响应。

使用 UIKit,我将在 ContainerView 中保留对 ContentView 的引用,并在点击按钮时调用其上的函数。但是,因为 SwiftUI 将所有 View 都作为结构,所以 contentView 在放入 ContainerViewbody 时被复制。因此,引用和显示的 ContentView 不同,我无法向 subview 发送消息。

代码:

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 发送消息并运行某些代码?

最佳答案

与其尝试存储对 subview 的引用,不如在它们之间建立绑定(bind)?在您的示例中,这可能是通过绑定(bind)到计数。

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 重置计数时,绑定(bind)将更新子项。

编辑:我看到您关于希望 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 组件所显示的模式。

关于ios - SwiftUI 将按钮点击发送到 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59757473/

相关文章:

navigationview - SwiftUI - ObservableObject 创建了多次

iOS:SocketRocket - 如何实现 SSL 握手

android - 状态栏隐藏 Cordova

iphone - 如何将特定的 TabBarItem 与 UITabBarController 一起使用?

ios - 在应用程序终止时安排本地通知

swift - 在不传递该类型示例的情况下告诉泛型函数它的类型

ios - SwiftUI:如何动态设置自定义 View 大小

ios - 设置 JTCalendar 单元格的大小

swift - 什么是 NSObject<Protocol> 的 swift 等价物?

ios - SwiftUI:在呈现工作表时防止 View 刷新