提问人:Alexnnd 提问时间:11/10/2023 更新时间:11/10/2023 访问量:58
我需要一些关于小型 SwiftUI 视图逻辑的帮助
I need some help for the logic of a small SwiftUI view
问:
我有一个带有 3 个开关和 1 个按钮的视图。起初,所有的开关都是假的,你只能使一个开关为真。此外,该按钮仅在 和 之间存在差异时才有效。customOption
newCustomOption
在可能的 4 种情况下,只有 2 种适用于我当前的代码:
1-您从所有开关开始,打开一个并确认。还行false
true
2-您从只有一个开关开始,进行并确认。还行true
false
3-您从所有开关开始,打开一个开关,打开另一个开关,然后获得相应的值。不行false
true
true
None
4- 像 3 一样,但您已经打开了一个开关。不行true
我发现了问题:设置为在获得正确的值而不是相反的值之后,但我不知道如何解决它。有什么想法吗?newCustomOption
None
import SwiftUI
struct ExampleView: View {
@Environment(\.dismiss) private var dismiss
@AppStorage("customOption") private var customOption = "None"
@State private var newCustomOption = "None"
@State private var optionOne = false
@State private var optionTwo = false
@State private var optionThree = false
var body: some View {
VStack {
Toggle("Option One", isOn: $optionOne)
.onAppear { load() }
.onChange(of: optionOne) { _ in
newCustomOption = optionOne ? "optionOne" : "None"
print(newCustomOption)
if optionOne {
optionTwo = false
optionThree = false
}
}
Toggle("Option Two", isOn: $optionTwo)
.onChange(of: optionTwo) { _ in
newCustomOption = optionTwo ? "optionTwo" : "None"
print(newCustomOption)
if optionTwo {
optionOne = false
optionThree = false
}
}
Toggle("Option Three", isOn: $optionThree)
.onChange(of: optionThree) { _ in
newCustomOption = optionThree ? "optionThree" : "None"
print(newCustomOption)
if optionThree {
optionOne = false
optionTwo = false
}
}
Button("Confirm", action: { confirm() })
.opacity(customOption == newCustomOption ? 0.5 : 1)
.disabled((customOption == newCustomOption ? true : false))
}
}
private func load() {
newCustomOption = customOption
switch newCustomOption {
case "optionOne":
optionOne = true
case "optionTwo":
optionTwo = true
case "optionThree":
optionThree = true
default /* "None" */:
return
}
}
private func confirm() {
customOption = newCustomOption
dismiss()
}
}
提前致谢!
答:
1赞
Joakim Danielson
11/10/2023
#1
我建议你改用一个,并将其样式化为单选按钮组,它将需要更少的代码和更简单的逻辑Picker
struct ExampleView: View {
@Environment(\.dismiss) private var dismiss
@AppStorage("customOption") private var customOption = "None"
var body: some View {
VStack {
Picker(selection: $customOption, label: Text("Option:")) {
Text("One").tag("optionOne")
Text("Two").tag("optionTwo")
Text("Three").tag("optionThree")
Text("None").tag("None")
}.pickerStyle(RadioGroupPickerStyle())
Button("Dismiss") { dismiss() }
}
}
}
——
这是一个没有“无”选项的替代解决方案
struct ExampleView: View {
@Environment(\.dismiss) private var dismiss
@AppStorage("customOption") private var customOption: String = "None"
@State private var selectedOption: String = "None"
var body: some View {
VStack {
Picker(selection: $selectedOption, label: Text("Option:")) {
Text("One").tag("optionOne")
Text("Two").tag("optionTwo")
Text("Three").tag("optionThree")
}.pickerStyle(RadioGroupPickerStyle())
Button("Dismiss") {
customOption = selectedOption
dismiss()
}
.disabled(selectedOption == "None")
}
.onAppear { selectedOption = customOption }
}
}
——
下一步是改用枚举来保存不同的选项。
评论
0赞
Alexnnd
11/10/2023
是的,我知道,但我真的不想作为一种选择。我会坚持下去,但如果我没有找到任何解决方案,我将不得不使用“无线电选择器”选项。None
0赞
Joakim Danielson
11/10/2023
也许你应该在你的问题中更清楚地表明你不想要“无”。
0赞
Joakim Danielson
11/10/2023
我修改了我的答案,不包括“无”作为选项
0赞
Alexnnd
11/10/2023
实际上,您以前的解决方案是最好的。我别无选择,只能使用带选项。但最好的方法是使用或等价物来获得类似 Safari 的“历史”之类的东西。谢谢,我明天会试试这个。Picker
None
.pickerStyle(.inline)
1赞
Benzy Neez
11/10/2023
#2
作为评论,我建议您使用单选按钮而不是切换来实现。如果您仅针对 macOS,则可以使用 (请参阅其他答案),但对于 iOS,您需要以不同的方式实现。RadioGroupPickerStyle
以下是如何使用 SwiftUI 答案中的 To be found 来完成:如何在 SwiftUI 中实现单选按钮(这是我的答案)。SelectionIndicator
- 它开始时没有选择任何选项(= 无)。
- 选择选项后,可以更改选择,但无法返回到无选择。
- 可能的选项由枚举定义。如果你愿意,你可以用字符串来完成这一切,但我建议,如果选项都是预定义的,那么枚举会更干净(首先,没有错别字导致错误的可能性)。
CustomOption
enum CustomOption: String {
case none = "None"
case one = "optionOne"
case two = "optionTwo"
case three = "optionThree"
}
struct ExampleView: View {
@Environment(\.dismiss) private var dismiss
@AppStorage("customOption") private var customOption = CustomOption.none.rawValue
@State private var newCustomOption = CustomOption.none
private func radioButtonItem(label: String, choice: CustomOption) -> some View {
HStack {
// see https://stackoverflow.com/a/75856182/20386264
SelectionIndicator(isSelected: newCustomOption == choice)
Text(label)
}
.onTapGesture {
withAnimation { newCustomOption = choice }
}
}
var body: some View {
VStack(alignment: .leading) {
radioButtonItem(label: "Option One", choice: .one)
radioButtonItem(label: "Option Two", choice: .two)
radioButtonItem(label: "Option Three", choice: .three)
Button("Confirm", action: { confirm() })
.opacity(newCustomOption.rawValue == customOption || newCustomOption == .none ? 0.5 : 1)
.disabled(newCustomOption.rawValue == customOption || newCustomOption == .none)
}
.onAppear { load() }
}
private func load() {
newCustomOption = CustomOption(rawValue: customOption) ?? .none
}
private func confirm() {
customOption = newCustomOption.rawValue
dismiss()
}
}
评论
0赞
Alexnnd
11/10/2023
谢谢,我明天会检查这个。
评论