swiftui - 如何单独和整体同时控制视图
问题描述
所以我遇到了一个我从未遇到过的问题。下图中是包含许多视图(单个阿拉伯语块)的父视图。
当用户得到正确答案时,该块将变为灰色并禁用。这是通过让单个语言块拥有视图并更改该状态来实现的。@State private var isDisabled = false
但最终如果用户回答每一个,那么所有的块都会变成灰色。然后如何将所有单独拥有的视图 Bool 状态重置为 true?
我不能让父视图拥有 Bool,因为尽管这会将所有视图重置为正常状态,但当再次禁用单个视图时,只会禁用它们,当然这是不希望的。
如果需要,将发布一个工作示例。谢谢。
解决方案
有几种(很多?)不同的可能方法,但这里有一个:
class StateManager : ObservableObject {
@Published var states = Array(repeating: false, count: 6)
func reset() {
states = states.map { _ in
false
}
}
}
struct ContentView : View {
@ObservedObject var vm = StateManager()
var body: some View {
VStack {
Box(state: $vm.states[0])
Box(state: $vm.states[1])
Box(state: $vm.states[2])
Box(state: $vm.states[3])
Box(state: $vm.states[4])
Box(state: $vm.states[5])
Button(action: {
vm.reset()
}) {
Text("Reset")
}
}
}
}
struct Box : View {
@Binding var state : Bool
var body: some View {
Button(action: {
state.toggle()
}) {
Text(state ? "Disabled" : "Enabled")
}
.disabled(state)
}
}
我正在使用一个 ObservedObject 来跟踪所有状态。当一个项目被点击时,它会在状态数组中的正确索引处发送它的值。
重置按钮只需将所有状态更改回 即可false
。
通过将您的状态保持在一个地方(ObservableObject),您有更多机会根据其他项目的状态改变状态,而不会遇到您遇到的问题,其中子视图只知道自己的状态并且不知道无法控制其他人。
此外,通过使用Array
状态,您可以避免制作一堆重复的 @State 项目。请注意,Array
也可能包含Boolean
比值更复杂的东西——它可能是关于该对象状态的完整信息结构。
更新: ObservableObject 被传递的版本:
class StateManager : ObservableObject {
@Published var states = Array(repeating: false, count: 6)
func reset() {
states = states.map { _ in
false
}
}
}
struct ContentView : View {
@ObservedObject var vm = StateManager()
var body: some View {
VStack {
Box(index: 0, stateManager: vm)
Box(index: 1, stateManager: vm)
Box(index: 2, stateManager: vm)
Box(index: 3, stateManager: vm)
Box(index: 4, stateManager: vm)
Box(index: 5, stateManager: vm)
Button(action: {
vm.reset()
}) {
Text("Reset")
}
}
}
}
struct Box : View {
var index : Int
@ObservedObject var stateManager : StateManager
var state : Bool {
stateManager.states[index]
}
var body: some View {
Button(action: {
stateManager.states[index].toggle()
}) {
Text(state ? "Disabled" : "Enabled")
}
.disabled(state)
}
}
推荐阅读
- javascript - 将多个事件添加到同一函数会导致超出最大堆栈大小
- javascript - 在期望值时得到“未定义”
- php - Apache 和 php-fpm 不适用于带有正斜杠的脚本名称
- ruby-on-rails - 如何在我的 ConnectionAdapter 回调中使用设计方法?
- sabre - BaseFare 等于 GetReservationRS 中的 BT
- php - 注意:unserialize(): WordPress 插件 Accordion 中偏移 0 字节的错误
- angular - 子组件中的 Angular @Input 也会更新父组件中的值
- python - 无法将 Gunicorn/Flask HelloWorld 扩展到超过 125 RPS
- javascript - 检查不和谐链接并删除
- javascript - How to find the width of a text-field in symbol type in mapbox