SwiftUI 为啥 Picker 上的输入不起作用?
Posted
技术标签:
【中文标题】SwiftUI 为啥 Picker 上的输入不起作用?【英文标题】:SwiftUI Why would the input on Picker not be functioning?SwiftUI 为什么 Picker 上的输入不起作用? 【发布时间】:2021-03-13 13:42:36 【问题描述】:我对 SwiftUI 还是很陌生,我需要社区的帮助来理解为什么在以下代码中选择任何 Picker 选项似乎都不起作用,要么不可选择,因此不会触发任何操作,要么被选中,它不会触发任何东西。
非常感谢您让我知道下划线的概念。
德沃
import SwiftUI
struct ContentView: View
@State private var measureToConvert = ""
@State private var conversionFromMeasure = "km"
@State private var convertedToMeasure = "m"
let measure = ["m", "km", "ft", "yd", "mi"]
func convertInMillimeters(input: String, number: String) -> Double
var value: Double = 0
if let realNumber = Double(number)
switch input
case "m":
let conversion = (Double(realNumber) * 1_000)
value = conversion
case "km":
let conversion = (Double(realNumber) * 1_000_000)
value = conversion
case "ft":
let conversion = (Double(realNumber) * 304.8)
value = conversion
case "yd":
let conversion = (Double(realNumber) * 914.4)
return conversion
case "mi":
let conversion = (Double(realNumber) * 1_609_344)
value = conversion
default:
let conversion = -2.0
value = conversion
print("value in millimeters is \(value)")
return value
func convertToNewMeasure(input: String, number: Double) -> Double
var value: Double = 0
switch input
case "m" :
let conversion = (number / 1_000)
value = conversion
case "km":
let conversion = (number / 1_000_000)
value = conversion
case "ft":
let conversion = (number / 304.8)
value = conversion
case "yd":
let conversion = (number / 914.4)
return conversion
case "mi":
let conversion = (number / 1_609_344)
value = conversion
default:
let conversion = -1.0
value = conversion
print("value converted is \(value)")
return value
var inMillimeters : Double
return convertInMillimeters(input: conversionFromMeasure, number: measureToConvert)
var result: Double
return convertToNewMeasure(input: convertedToMeasure, number: inMillimeters)
var body: some View
NavigationView
Form
Section(header: Text("Value to convert:"))
TextField("Enter a measure", text: $measureToConvert).keyboardType(.decimalPad)
Section(header: Text("Select input measure"))
Picker("From", selection: $conversionFromMeasure)
ForEach(0 ..< measure.count)
Text("\(self.measure[$0])")
.pickerStyle(SegmentedPickerStyle())
Section(header: Text("Select output measure"))
Picker("To", selection: $convertedToMeasure)
ForEach(0 ..< measure.count)
Text("\(self.measure[$0])")
.pickerStyle(SegmentedPickerStyle())
Section(header: Text("Converted value"))
Text("\(result, specifier: "%.2f")")
.navigationBarTitle("Measure Converter")
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【问题讨论】:
选择器无法工作,因为它没有一组可供选择的项目。您会在我的回答中看到,选择器现在有一系列可供选择的项目 感谢一百万的快速解决方案,我将立即学习。再次感谢,我非常感谢您的帮助! 【参考方案1】:当使用带有这几个选项的选择器时,使用枚举来存储值非常方便,您也可以使用枚举来存储您的函数并返回您想要的结果。你可以了解更多关于枚举here
创建枚举后,使其符合 CaseIterable,这将为您提供所有案例的数组,然后您将在 ForEach 中使用这些案例。
您还给它一个 rawValue,它将作为填充每个选择器选项的内容。很清楚我在那里的代码中做了什么。
import SwiftUI
struct ContentView: View
enum Unit: String, CaseIterable
case meters = "m"
case kilometers = "km"
case feet = "ft"
case yards = "yd"
case miles = "mi"
@State private var unitSelection: Unit = .meters
@State private var measureToConvert = ""
@State private var conversionFromMeasure = "km"
@State private var convertedToMeasure = "m"
let measure = ["m", "km", "ft", "yd", "mi"]
func convertInMillimeters(input: String, number: String) -> Double
var value: Double = 0
if let realNumber = Double(number)
switch input
case "m":
let conversion = (Double(realNumber) * 1_000)
value = conversion
case "km":
let conversion = (Double(realNumber) * 1_000_000)
value = conversion
case "ft":
let conversion = (Double(realNumber) * 304.8)
value = conversion
case "yd":
let conversion = (Double(realNumber) * 914.4)
return conversion
case "mi":
let conversion = (Double(realNumber) * 1_609_344)
value = conversion
default:
let conversion = -2.0
value = conversion
print("value in millimeters is \(value)")
return value
func convertToNewMeasure(input: String, number: Double) -> Double
var value: Double = 0
switch input
case "m" :
let conversion = (number / 1_000)
value = conversion
case "km":
let conversion = (number / 1_000_000)
value = conversion
case "ft":
let conversion = (number / 304.8)
value = conversion
case "yd":
let conversion = (number / 914.4)
return conversion
case "mi":
let conversion = (number / 1_609_344)
value = conversion
default:
let conversion = -1.0
value = conversion
print("value converted is \(value)")
return value
var inMillimeters : Double
return convertInMillimeters(input: conversionFromMeasure, number: measureToConvert)
var result: Double
return convertToNewMeasure(input: convertedToMeasure, number: inMillimeters)
var body: some View
NavigationView
Form
Section(header: Text("Value to convert:"))
TextField("Enter a measure", text: $measureToConvert).keyboardType(.decimalPad)
Section(header: Text("Select input measure"))
Picker("From", selection: $unitSelection)
ForEach(Unit.allCases, id: \.self) unit in
Text(unit.rawValue)
.pickerStyle(SegmentedPickerStyle())
Section(header: Text("Select output measure"))
Picker("To", selection: $convertedToMeasure)
ForEach(0 ..< measure.count)
Text("\(self.measure[$0])")
.pickerStyle(SegmentedPickerStyle())
Section(header: Text("Converted value"))
Text("\(result, specifier: "%.2f")")
.navigationBarTitle("Measure Converter")
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【讨论】:
【参考方案2】:你可以通过改变这个来让你的选择器工作:
ForEach(0 ..< measure.count)
Text("\(self.measure[$0])")
到这里:
ForEach(measure, id: \.self)
Text($0)
所以这两个部分应该是:
Section(header: Text("Select input measure"))
Picker("From", selection: $conversionFromMeasure)
ForEach(measure, id: \.self)
Text($0)
.pickerStyle(SegmentedPickerStyle())
Section(header: Text("Select output measure"))
Picker("To", selection: $convertedToMeasure)
ForEach(measure, id: \.self)
Text($0)
.pickerStyle(SegmentedPickerStyle())
【讨论】:
太好了,感谢一百万,通过您的所有输入,我学到了很多东西。再次感谢。以上是关于SwiftUI 为啥 Picker 上的输入不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI 中,我如何知道 Picker 选择何时更改?为啥 didSet 不起作用?
iOS 15 SwiftUI 3 Picker 绑定在更改@State 值后不起作用