如何在 SwiftUI 中重置子视图?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中重置子视图?【英文标题】:How to reset a subview in SwiftUI? 【发布时间】:2020-08-01 20:47:39 【问题描述】:下面是我正在使用的代码的简化版本。但是每当我 resetKeyboard() 它仍然显示以前的键盘。无论如何,当我调用 resetKeyboard() 时,它会用新的 KeyboardView 替换键盘吗?
struct GameView: View
@State var myKeyboard = KeyboardView()
var body: some View
VStack
Button("Change Keyboard")
myKeyboard.change()
myKeyboard
Button("Reset Keyboard")
resetKeyboard()
func resetKeyboard()
self.myKeyboard = KeyboardView()
【问题讨论】:
你没有调用 resetKeyboard()。 @MohammadRahchamani 抱歉,我忘了把它添加到帖子中,我刚刚修复了它。但这是在我的实际项目中调用的,但我仍然遇到错误。KeyboardView
是什么,.change()
有什么作用?
@NewDev KeyboardView 是一堆自定义按钮,当您按下切换按钮时。例如 .change() 可以切换一个随机按钮。不过应该没太大关系吧?因为我遇到的问题只是试图用一个新的keyboardView替换一个。
@JackBodine,其中一些确实很重要,因为我不明白“替换视图”是什么意思。你说得对,具体的实现并不重要,但我认为你需要解释你到底想对KeyboardView
或GameView
发生什么。
【参考方案1】:
SwiftUI 从其父级的body
中的View
对象构造一个视图树。
所以,SwiftUI 得到的是myKeyboard
的初始副本(请记住,它是值类型struct
),而不是您要更改的副本。
在正常使用情况下,您不会将各种 View 的实例存储为变量(我的意思是,您可以,但您需要深入了解发生了什么)。
您可能想要更改驱动子视图的数据。这些数据(应该)在哪里?这取决于你想做什么。
在大多数情况下,父母“拥有”状态,即拥有孩子所依赖的某些数据的真实来源。然后更改状态并通过其init
将状态传递给孩子是微不足道的:
struct ChildView: View
let number: Int
var body: some View
Text("\(number)")
struct ParentView: View
@State var random: Int = Int.random(1...100)
var body: some View
VStack()
ChildView(number: random)
Button("randomize")
self.random = Int.random(1...100)
但是,比如说,父母不想做随机化 - 即孩子应该处理它。
正确的方法是为子级创建一个视图模型,父级(或父级自己的视图模型)可以拥有并通过init
传递,然后视图模型将处理随机化的细微差别。
class ChildVM: ObservableObject
@Published var random = Int.random(1...100)
func change()
random = Int.random(1...100)
父级创建ChildVM
的实例并将其传递给子级:
struct ParentVuew: View
let childVM = ChildVM()
var body: some View
VStack()
ChildView(vm: childVm)
Button("randomize")
self.childVM.change()
而子视图只是由视图模型驱动:
struct ChildView: View
@ObservedObject let vm: ChildVM
var body: some View
Text("\(vm.random)")
显然,这是一个可以通过多种方式实现的简化示例。
父母可以通过不同的方式向孩子“传达信息”。
但总体而言,View
s 应该被认为是声明性结构——而不是活生生的实例——而数据是驱动这些视图变化的驱动力。你需要决定谁最能掌握真相的来源。
【讨论】:
以上是关于如何在 SwiftUI 中重置子视图?的主要内容,如果未能解决你的问题,请参考以下文章