(SwiftUI)如何在视图加载时隐藏文本并在点击切换后变得可见
(SwiftUI) How to make text hidden when view loads and become visible once toggle is tapped
我正在尝试使用 toggle
创建视图。切换更改 ui 首选项。更改切换时,它会更改下面的 Text
。目前最简单的方法是
VStack {
Toggle("toggle me", isOn: $isOn)
Text( isOn ? "I've been toggled once more" : "I've been toggled again" )
}
我想要的是 Text( isOn ? "I've been toggled once more" : "I've been toggled again" )
被隐藏,直到 开关被交互。打开或关闭它都没有关系,我想在与切换进行交互后使文本可见。我试过使用 .onChange(of: perform: )
但 perform:
要求 ui res 一个无效的方法。所以我不能把文本放在那里。我已尝试使用 boolean/opacity 修复程序,如答案 中所示,但同样的问题。不能在执行中更改布尔值。只允许 void 方法。我确实尝试使用 onTapGesture
但那根本不起作用。我在那里有一份打印声明,从未打印过。不知道还能做什么。是否可以在与切换进行交互之前隐藏文本?这是我的代码
struct ProfileView: View {
@State private var isOn = UserDefaults.standard.bool(forKey: "isOn")
@State private var showText = false
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: $isOn)
.onTapGesture {
print("toggled") // this never prints
}
// .onChange(of: isOn, perform: { value in
// value ? Text("yes") : Text("no")
// print("value = \(value)")
// })
// the Text here never shows up. and can't set showText = true here
Text( isOn ? "Thank you." : "Toggled again" )
.opacity(showText ? 1 : 0)
// from the linked Whosebug answer. trying to make this boolean work. is it a lost cause?
} // vstack 1
} // vstack 0
.frame(
width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height - 200,
alignment: .top)
}
}
所以我问的是可能的吗?感谢您的帮助!
您可以继续为 showText
使用 @State
变量,根据您的要求,只有在与 Toggle
进行交互时才会显示该变量。与其使用使用 UserDefaults
值初始化的 @State
变量,您可能希望对 isOn
.
使用 @AppStorage
struct ProfileView: View {
@AppStorage("isOn") private var isOn : Bool = false //@AppStorage syncs this value with UserDefaults automatically
@State private var showText = false
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: $isOn)
.onChange(of: isOn, perform: { value in
showText = true //Once the toggle is interacted with, set showText to true
})
if showText { //only show the text if showText == true
Text( isOn ? "Thank you." : "Toggled again" )
}
} // vstack 1
} // vstack 0
.padding(.bottom, 200) //try not to use UIScreen dimensions in SwiftUI -- default to using padding instead when possible
}
}
解决此问题的方法略有不同。您可以让 @AppStorage
存储一个可选值,只要您将可选值扩展到
符合RawRepresentable
。这允许您消除 showText
状态变量,并允许您具有 3 种可能性的确定状态,true、false 和 nil。由于您不希望在 Toggle
被切换一次之前显示文本,因此 nil 状态可以让您知道这一点。一旦 Toggle
被切换,isOn
从那时起将有一个 true 或 false 值,除非你在其他地方再次将它设置为 nil。
这增加了一种复杂性。 Toggle
不带 Bool?。因此,您必须为其编写自己的绑定,以便将确定的值传递给 Toggle
.
struct ProfileView: View {
@AppStorage("isOn") private(set) var isOn: Bool? = nil
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: Binding<Bool>(
get: { isOn ?? false },
set: { isOn = [=10=] }
))
.onTapGesture {
print("toggled") // this never prints
}
Text( isOn == true ? "Thank you." : "Toggled again" )
// Compare isOn to nil, instead of use showText
.opacity(isOn != nil ? 1 : 0)
} // vstack 1
Spacer()
} // vstack 0
.padding()
}
}
// This extension allows Optionals to be written to @AppStorage
extension Optional: RawRepresentable where Wrapped: Codable {
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let json = String(data: data, encoding: .utf8)
else {
return "{}"
}
return json
}
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let value = try? JSONDecoder().decode(Self.self, from: data)
else {
return nil
}
self = value
}
}
我正在尝试使用 toggle
创建视图。切换更改 ui 首选项。更改切换时,它会更改下面的 Text
。目前最简单的方法是
VStack {
Toggle("toggle me", isOn: $isOn)
Text( isOn ? "I've been toggled once more" : "I've been toggled again" )
}
我想要的是 Text( isOn ? "I've been toggled once more" : "I've been toggled again" )
被隐藏,直到 开关被交互。打开或关闭它都没有关系,我想在与切换进行交互后使文本可见。我试过使用 .onChange(of: perform: )
但 perform:
要求 ui res 一个无效的方法。所以我不能把文本放在那里。我已尝试使用 boolean/opacity 修复程序,如答案 onTapGesture
但那根本不起作用。我在那里有一份打印声明,从未打印过。不知道还能做什么。是否可以在与切换进行交互之前隐藏文本?这是我的代码
struct ProfileView: View {
@State private var isOn = UserDefaults.standard.bool(forKey: "isOn")
@State private var showText = false
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: $isOn)
.onTapGesture {
print("toggled") // this never prints
}
// .onChange(of: isOn, perform: { value in
// value ? Text("yes") : Text("no")
// print("value = \(value)")
// })
// the Text here never shows up. and can't set showText = true here
Text( isOn ? "Thank you." : "Toggled again" )
.opacity(showText ? 1 : 0)
// from the linked Whosebug answer. trying to make this boolean work. is it a lost cause?
} // vstack 1
} // vstack 0
.frame(
width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height - 200,
alignment: .top)
}
}
所以我问的是可能的吗?感谢您的帮助!
您可以继续为 showText
使用 @State
变量,根据您的要求,只有在与 Toggle
进行交互时才会显示该变量。与其使用使用 UserDefaults
值初始化的 @State
变量,您可能希望对 isOn
.
@AppStorage
struct ProfileView: View {
@AppStorage("isOn") private var isOn : Bool = false //@AppStorage syncs this value with UserDefaults automatically
@State private var showText = false
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: $isOn)
.onChange(of: isOn, perform: { value in
showText = true //Once the toggle is interacted with, set showText to true
})
if showText { //only show the text if showText == true
Text( isOn ? "Thank you." : "Toggled again" )
}
} // vstack 1
} // vstack 0
.padding(.bottom, 200) //try not to use UIScreen dimensions in SwiftUI -- default to using padding instead when possible
}
}
解决此问题的方法略有不同。您可以让 @AppStorage
存储一个可选值,只要您将可选值扩展到
符合RawRepresentable
。这允许您消除 showText
状态变量,并允许您具有 3 种可能性的确定状态,true、false 和 nil。由于您不希望在 Toggle
被切换一次之前显示文本,因此 nil 状态可以让您知道这一点。一旦 Toggle
被切换,isOn
从那时起将有一个 true 或 false 值,除非你在其他地方再次将它设置为 nil。
这增加了一种复杂性。 Toggle
不带 Bool?。因此,您必须为其编写自己的绑定,以便将确定的值传递给 Toggle
.
struct ProfileView: View {
@AppStorage("isOn") private(set) var isOn: Bool? = nil
var body: some View {
VStack { // vstack 0
Text("Profile Page")
.font(.title)
Text("Are you ready to toggle?")
.font(.title2)
.multilineTextAlignment(.center)
VStack { // vstack 1
Toggle("toggle this", isOn: Binding<Bool>(
get: { isOn ?? false },
set: { isOn = [=10=] }
))
.onTapGesture {
print("toggled") // this never prints
}
Text( isOn == true ? "Thank you." : "Toggled again" )
// Compare isOn to nil, instead of use showText
.opacity(isOn != nil ? 1 : 0)
} // vstack 1
Spacer()
} // vstack 0
.padding()
}
}
// This extension allows Optionals to be written to @AppStorage
extension Optional: RawRepresentable where Wrapped: Codable {
public var rawValue: String {
guard let data = try? JSONEncoder().encode(self),
let json = String(data: data, encoding: .utf8)
else {
return "{}"
}
return json
}
public init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8),
let value = try? JSONDecoder().decode(Self.self, from: data)
else {
return nil
}
self = value
}
}