我刚开始学习SwiftUI,就卡在了某个地方!
我试图改变段样式的选择器数据源时,改变另一个段的值。但不知何故,它没有工作的预期!或者我可能有编码错误。有人能找出它吗?
下面是我的代码:
import SwiftUI
struct ContentView: View {
@State var selectedType = 0
@State var inputUnit = 0
@State var outputUnit = 1
let arrTypes = ["Temperature", "Length"]
var arrData: [String] {
switch self.selectedType {
case 0:
return ["Celsius", "Fahrenheit", "Kelvin"] //Temperature
case 1:
return ["meters", "kilometers", "feet", "yards", "miles"] //Length
default:
return ["Celsius", "Fahrenheit", "Kelvin"]
}
}
var body: some View {
NavigationView{
Form
{
Section(header: Text("Choose type"))
{
Picker("Convert", selection: $selectedType) {
ForEach(0 ..< 2, id: \.self)
{ i in
Text(self.arrTypes[i])
}
}
.pickerStyle(SegmentedPickerStyle())
}
Section(header: Text("From"))
{
Picker("", selection: $inputUnit) {
ForEach(0 ..< arrData.count, id: \.self)
{
Text(self.arrData[$0])
}
}
.pickerStyle(SegmentedPickerStyle())
}
Section(header: Text("To"))
{
Picker("", selection: $outputUnit) {
ForEach(0 ..< arrData.count, id: \.self)
{
Text(self.arrData[$0])
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
}
}
当我将段从Length
更改回Temperature
时,它以某种方式合并了数组。我尝试调试并在日志中打印arrData
计数,然后它打印了正确的结果,但没有更新UI!
**默认选择的第一段:**x1c 0d1x
更改段:
将段改回第一段:
任何帮助或建议将不胜感激。
5条答案
按热度按时间4uqofj5v1#
Nick Polychronakis在这个分叉中解决了它:https://github.com/nickpolychronakis/100DaysOfSwiftUI/tree/master/UnitCoverter
解决方案是将.id(:identifier:)添加到您的选取器中,使其唯一。
可观察变量:
主拾取器:
次要选取器之一,其内容由单位变量确定。
zqdjd7g92#
我不确定SwiftUI为什么会这样,我觉得这是个错误(如果我错了请纠正我)。我能建议的是添加温度和长度的单独拾取器,并根据当前选择的类型隐藏它们。为了代码的可重用性,我将拾取器添加到了另一个文件中。
我的自定义选取器
内容视图
**注:**必须使用不同的状态变量来跟踪温度和长度选择。
mccptt673#
结合前面两个答案:
内容视图
单位选取器
参见https://github.com/hugofalkman/UnitConverter.git
q35jwt9p4#
仅供参考:以上答案不适用于SwiftUI中的Wheelpickerstyle。单位计数将保持初始值,因此如果您从温度开始,然后切换到长度,则将丢失长度数组的最后两个值。如果您选择相反的方式,则应用将崩溃并出现越界。
我花了很长时间才找到一个解决方案。看起来这是Wheelpickerstyle中的一个bug。解决方法是更新picker的ID,这会提示它重新加载所有数据源。我在下面提供了一个示例。
qxsslcnc5#
只需在ForEach(Picker)中为文本设置标记即可。