iSp*_*n17 11 ios swift swiftui
我有以下观点(去掉不相关的部分):
struct Chart : View {
var xValues: [String]
var yValues: [Double]
@State private var showXValues: Bool = false
var body = some View {
...
if showXValues {
...
} else {
...
}
...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我想添加一种从外部修改这个值的方法,所以我添加了一个函数:
func showXValues(show: Bool) -> Chart {
self.showXValues = show
return self
}
Run Code Online (Sandbox Code Playgroud)
所以我像这样从外部构建图表视图:
Chart(xValues: ["a", "b", "c"], yValues: [1, 2, 3])
.showXValues(true)
Run Code Online (Sandbox Code Playgroud)
但它的工作方式就好像该值仍然为假。我究竟做错了什么?我认为更新 @State 变量应该更新视图。总的来说,我对 Swift 很陌生,对 SwiftUI 更是如此,我是否缺少某种应该在这里使用的特殊技术?
小智 6
正如在评论中提到的那样,@Binding
是要走的路。
这是一个最小的示例,显示了您的代码的概念:
struct Chart : View {
var xValues: [String]
var yValues: [Double]
@Binding var showXValues: Bool
var body: some View {
if self.showXValues {
return Text("Showing X Values")
} else {
return Text("Hiding X Values")
}
}
}
struct ContentView: View {
@State var showXValues: Bool = false
var body: some View {
VStack {
Chart(xValues: ["a", "b", "c"], yValues: [1, 2, 3], showXValues: self.$showXValues)
Button(action: {
self.showXValues.toggle()
}, label: {
if self.showXValues {
Text("Hide X Values")
}else {
Text("Show X Values")
}
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
无需创建func
-s。我所要做的就是不将属性标记为私有,而是给它们一个初始值,这样它们将在构造函数中成为可选的。因此用户可以指定它们,也可以不关心。像这样:
var showXLabels: Bool = false
这样构造函数就是Chart(xLabels:yLabels)
or Chart(xLabels:yLabels:showXLabels)
。
问题与@State无关。
几年后编辑
实际上,对于二元期权,有一种更简洁的方法可以解决这个问题,例如显示/隐藏内容。对于多于 2 路的配置,仍然需要使用不同的参数。
关键是OptionSet
s 正是针对这种用例,并且可以在 Foundation 等 Apple 框架中找到它们。
所以,我们只需添加一个Chart.Options
结构:
extension Chart {
struct Options: OptionSet {
let rawValue: Int
static var showXValueLabels = Self(rawValue: 1 << 0)
static var showYValueLabels = Self(rawValue: 1 << 1)
[... add more options if you want]
}
}
Run Code Online (Sandbox Code Playgroud)
然后,视图本身仍然更加紧凑,因为它只有一个用于二进制设置的变量:
struct Chart: View {
var xValues: [String]
var yValues: [Int]
var options: Chart.Options = []
var body: some View {
VStack {
Text("A chart")
if options.contains(.showXValueLabels) {
[... whatever xValue label specific view]
}
if options.contains(.showYValueLabels) {
[... whatever yValue label specific view]
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以构建Chart
这样的:
Chart(xValues: ["a", "b", "c"],
yValues: [1, 2, 3],
options: [.showXValueLabels, .showYValueLabels])
Run Code Online (Sandbox Code Playgroud)
或者
Chart(xValues: ["a", "b", "c"],
yValues: [1, 2, 3],
options: [.showXValueLabels])
Run Code Online (Sandbox Code Playgroud)
或者只使用默认选项:
Chart(xValues: ["a", "b", "c"],
yValues: [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15921 次 |
最近记录: |