在 SwiftUI 中的 2 个子视图之间共享 @State var Bool
Sharing a @State var Bool between 2 child Views in SwiftUI
我是一名设计师,我正在努力学习 SwiftUI 以获取乐趣,同时也确保我更多地了解我的开发团队对我的需求。
还有一些非常简单的事情我做不到!
正如您从下面这段代码中看到的,我只想在 var showHello 为 true 时显示一段文本,而且效果很好。
import SwiftUI
struct ContentView: View {
@State var showHello = true
var body: some View {
VStack {
Spacer()
Button("Show Hello", action: { showHello.toggle() })
.padding()
Spacer()
Text("This is your message:")
.padding()
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
但是当我想通过使用多个视图来做完全相同的事情时,它不起作用!
// Parent file
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
TopView()
BottomView()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// Child file 1
import SwiftUI
struct TopView: View {
@State var showHello = true
var body: some View {
Button("Show Hello", action: { showHello.toggle() })
.padding()
}
}
struct TopView_Previews: PreviewProvider {
static var previews: some View {
TopView()
}
}
// Child file 2
import SwiftUI
struct BottomView: View {
var body: some View {
Text("This is your message:")
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
}
}
struct BottomView_Previews: PreviewProvider {
static var previews: some View {
BottomView()
}
}
而且我知道我们不能从不同的视图共享一个 var,所以我在互联网上花了几个小时来了解更多关于使用 @State/@Binding 或 @EnvironmentObject 的信息,但所有的例子都是关于从一个视图共享一个 var父视图到子视图,但不是子视图之间到父视图。
此外,无论我在做什么,Xcode 总是出错,因为某处缺少某些东西!
我需要你的帮助,在此先感谢! :P
I have spent hours on Internet to learn more about using @State/@Binding or @EnvironmentObject
所以您走在正确的道路上,因为您确实需要使用 @Binding
。也许你只是对如何连接点有错误的想法。
基本上,您需要 parent 或 ContentView
中的 @State
属性 包装器,因为您想在 [=] 中共享相同的 属性 35=] 视图并对它的任何突变做出反应,你在 child 视图中使用 @Binding
属性 包装器。
所以你会得到这样的东西:
struct ContentView: View {
@State var showHello = true
var body: some View {
VStack {
TopView(showHello: $showHello)
BottomView(showHello: showHello)
}
}
}
struct TopView: View {
@Binding var showHello: Bool
var body: some View {
Button("Show Hello", action: { showHello.toggle() })
.padding()
}
}
struct BottomView: View {
let showHello: Bool
var body: some View {
Text("This is your message:")
Text("Hello")
.opacity(showHello ? 1 : 0)
}
}
我会为 SwiftUI 推荐一些其他好的资源:
您不需要在此特定示例中使用 @Binding
,因为您没有在子视图中更改 showHello
的状态。 @Binding
用于 two-way 数据流(即从父级到子级,反之亦然)。如果您的数据流是单向的(即从父级到子级),您可以在子视图中使用简单的 let
。
还有,不是这个:
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
你应该这样做:
Text("Hello")
.opacity(showHello ? 1 : 0)
第一种方法创建两个不同且独立的 View
,而第二种方法创建一个 View
,您可以根据需要更改其 opacity
修饰符。对于像这样的简单 View
层次结构来说没什么大不了的,但是一旦你开始获得更复杂的层次结构,它将有助于 SwiftUI 的视图差异和 re-rendering。它有助于动画,因为它是一个 View
上的 属性 正在改变而不是两个 View
切换出来。
这样也更容易阅读。
好的,一切正常。感谢你们所有人,尤其是@NicolasElPapu。
此外,该解决方案适用于模拟器,但不适用于 PreviewProviders。如果你还是像我一样报错,只需更新底部的这些代码即可。
struct TopView_Previews: PreviewProvider {
static var previews: some View {
TopView(showHello: .constant(true))
}
}
struct BottomView_Previews: PreviewProvider {
static var previews: some View {
BottomView(showHello: true) // Or .constant(true) again if you're not using a let for the BottomView!
}
}
此外,如果您想了解为什么需要在 PreviewProvider 中添加虚假信息,原因如下:https://www.hackingwithswift.com/forums/swiftui/binding-variable-won-t-preview/10974
再次感谢大家!
我是一名设计师,我正在努力学习 SwiftUI 以获取乐趣,同时也确保我更多地了解我的开发团队对我的需求。
还有一些非常简单的事情我做不到!
正如您从下面这段代码中看到的,我只想在 var showHello 为 true 时显示一段文本,而且效果很好。
import SwiftUI
struct ContentView: View {
@State var showHello = true
var body: some View {
VStack {
Spacer()
Button("Show Hello", action: { showHello.toggle() })
.padding()
Spacer()
Text("This is your message:")
.padding()
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
但是当我想通过使用多个视图来做完全相同的事情时,它不起作用!
// Parent file
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
TopView()
BottomView()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// Child file 1
import SwiftUI
struct TopView: View {
@State var showHello = true
var body: some View {
Button("Show Hello", action: { showHello.toggle() })
.padding()
}
}
struct TopView_Previews: PreviewProvider {
static var previews: some View {
TopView()
}
}
// Child file 2
import SwiftUI
struct BottomView: View {
var body: some View {
Text("This is your message:")
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
}
}
struct BottomView_Previews: PreviewProvider {
static var previews: some View {
BottomView()
}
}
而且我知道我们不能从不同的视图共享一个 var,所以我在互联网上花了几个小时来了解更多关于使用 @State/@Binding 或 @EnvironmentObject 的信息,但所有的例子都是关于从一个视图共享一个 var父视图到子视图,但不是子视图之间到父视图。
此外,无论我在做什么,Xcode 总是出错,因为某处缺少某些东西!
我需要你的帮助,在此先感谢! :P
I have spent hours on Internet to learn more about using @State/@Binding or @EnvironmentObject
所以您走在正确的道路上,因为您确实需要使用 @Binding
。也许你只是对如何连接点有错误的想法。
基本上,您需要 parent 或 ContentView
中的 @State
属性 包装器,因为您想在 [=] 中共享相同的 属性 35=] 视图并对它的任何突变做出反应,你在 child 视图中使用 @Binding
属性 包装器。
所以你会得到这样的东西:
struct ContentView: View {
@State var showHello = true
var body: some View {
VStack {
TopView(showHello: $showHello)
BottomView(showHello: showHello)
}
}
}
struct TopView: View {
@Binding var showHello: Bool
var body: some View {
Button("Show Hello", action: { showHello.toggle() })
.padding()
}
}
struct BottomView: View {
let showHello: Bool
var body: some View {
Text("This is your message:")
Text("Hello")
.opacity(showHello ? 1 : 0)
}
}
我会为 SwiftUI 推荐一些其他好的资源:
您不需要在此特定示例中使用 @Binding
,因为您没有在子视图中更改 showHello
的状态。 @Binding
用于 two-way 数据流(即从父级到子级,反之亦然)。如果您的数据流是单向的(即从父级到子级),您可以在子视图中使用简单的 let
。
还有,不是这个:
if showHello == true {
Text("Hello")
} else {
Text("Hello")
.opacity(0)
}
你应该这样做:
Text("Hello")
.opacity(showHello ? 1 : 0)
第一种方法创建两个不同且独立的 View
,而第二种方法创建一个 View
,您可以根据需要更改其 opacity
修饰符。对于像这样的简单 View
层次结构来说没什么大不了的,但是一旦你开始获得更复杂的层次结构,它将有助于 SwiftUI 的视图差异和 re-rendering。它有助于动画,因为它是一个 View
上的 属性 正在改变而不是两个 View
切换出来。
这样也更容易阅读。
好的,一切正常。感谢你们所有人,尤其是@NicolasElPapu。
此外,该解决方案适用于模拟器,但不适用于 PreviewProviders。如果你还是像我一样报错,只需更新底部的这些代码即可。
struct TopView_Previews: PreviewProvider {
static var previews: some View {
TopView(showHello: .constant(true))
}
}
struct BottomView_Previews: PreviewProvider {
static var previews: some View {
BottomView(showHello: true) // Or .constant(true) again if you're not using a let for the BottomView!
}
}
此外,如果您想了解为什么需要在 PreviewProvider 中添加虚假信息,原因如下:https://www.hackingwithswift.com/forums/swiftui/binding-variable-won-t-preview/10974
再次感谢大家!