Swift 切换选择器值时,如何阻止应用程序崩溃?

Swift 切换选择器值时,如何阻止应用程序崩溃?,swift,swiftui,Swift,Swiftui,我正在制作一个单位转换器应用程序。除了一个问题外,它运行良好。当我更改第二个和第三个选择器的值,然后更改第一个选择器的值时,应用程序崩溃。我怀疑这是因为它被设置为超出范围的索引。有办法解决这个问题吗?当unitTypesIndex的值更改时,是否可以将fromUnitsIndex和toUnitsIndex的值设置回0 代码如下: func convert(_ value: Double, from sourceUnit: Dimension, to targetUnit: Dimension)

我正在制作一个单位转换器应用程序。除了一个问题外,它运行良好。当我更改第二个和第三个选择器的值,然后更改第一个选择器的值时,应用程序崩溃。我怀疑这是因为它被设置为超出范围的索引。有办法解决这个问题吗?当
unitTypesIndex
的值更改时,是否可以将
fromUnitsIndex
toUnitsIndex
的值设置回0

代码如下:

func convert(_ value: Double, from sourceUnit: Dimension, to targetUnit: Dimension) -> Double {
    let a = Measurement(value: value, unit: sourceUnit)
    let b = a.converted(to: targetUnit).value
    return b
}

struct ContentView: View {
    @State private var fromUnitsIndex:Int = 0
    @State private var toUnitsIndex:Int = 0
    @State private var unitTypesIndex:Int = 0
    private var unitTypesArr = ["Acceleration", "Angle", "Area", "Concentration of Mass", "Duration", "Electric Charge", "Electric Current", "Electric Potential Difference", "Electrical Resistance", "Energy", "Frequency", "Fuel Efficiency", "Length", "Mass", "Power", "Pressure", "Speed", "Temperature", "Volume"]
    private var unitsArr = [["Meters Per Second Squared", "Gravity"], ["Degrees", "Radians", "Arc Minutes", "Arc Seconds", "Gradians", "Revolutions"], ["Square Nanometers", "Square Micrometers", "Square Millimeters", "Square Centimeters", "Square Meters", "Square Kilometers", "Square Megameters", "Square Inches", "Square Feet", "Square Yards", "Square Miles", "Acres", "Hectares", "Ares"], ["Grams Per Liter", "Milligrams Per Deciliter", "Millimoles Per Liter"], ["Seconds", "Minutes", "Hours"], ["Coulombs", "Microampere Hours", "Milliampere Hours", "Ampere Hours", "Kiloampere Hours", "Megaampere Hours"], ["Microamperes", "Milliamperes", "Amperes", "Kiloamperes", "Megaamperes"], ["Microvolts", "Millivolts", "Volts", "Kilovolts", "Megavolts"], ["Microohms", "Milliohms", "Ohms", "Kiloohms", "Megaohms"], ["Joules", "Kilojoules", "Calories", "Kilocalories", "Kilowatt Hours"], ["Nanohertz", "Microhertz", "Millihertz", "Hertz", "Kilohertz", "Megahertz", "Gigahertz", "Terahertz"], ["Liters Per 100 km", "Miles Per Gallon", "Miles Per Imperial Gallon"], ["Picometers", "Nanometers", "Micrometers", "Millimeters", "Centimeters", "Decimeters", "Meters", "Decameters", "Hectometers", "Kilometers", "Megameters", "Inches", "Feet", "Yards", "Miles", "Nautical Miles", "Light Years", "Astronomical Units", "Parsecs", "Fathoms", "Furlongs", "Scandinavian Miles"], ["Picograms", "Nanograms", "Micrograms", "Milligrams", "Centigrams", "Decigrams", "Grams", "Kilograms", "Metric Tons", "Ounces", "Pounds", "Stones", "Short Tons", "Carats", "Ounces Troy", "Slugs"], ["Femtowatts", "Picowatts", "Nanowatts", "Microwatts", "Milliwatts", "Watts", "Kilowatts", "Megawatts", "Gigawatts", "Terawatts", "Horsepower"], ["Pascals", "Hectopascals", "Kilopascals", "Megapascals", "Gigapascals", "Millibars", "Bars", "Pounds Per Square Inch", "Millimeters of Mercury", "Inches of Mercury"], ["Meters Per Second", "Kilometers Per Hour", "Miles Per Hour", "Knots"], ["Degrees Celsius", "Degrees Fahrenheit", "Degrees Kelvin"], ["Milliliters", "Centiliters", "Deciliters", "Liters", "Kiloliters", "Megaliters", "Cubic Millimeters", "Cubic Decimeters", "Cubic Meters", "Cubic Kilometers", "Fluid Ounces", "Cups", "Pints", "Quarts", "Gallons", "Cubic Inches", "Cubic Feet", "Cubic Yards", "Cubic Miles", "Acre Feet", "Bushels", "Teaspoons", "Tablespoons", "Imperial Teaspoons", "Imperial Tablespoons", "Imperial Fluid Ounces", "Imperial Pints", "Imperial Quarts", "Imperial Gallons", "Metric Cups"]]
    private var convUnitsArr = [[UnitAcceleration.metersPerSecondSquared, UnitAcceleration.gravity], [UnitAngle.degrees, UnitAngle.radians, UnitAngle.arcMinutes, UnitAngle.arcSeconds, UnitAngle.gradians, UnitAngle.revolutions], [UnitArea.squareNanometers, UnitArea.squareMicrometers, UnitArea.squareMillimeters, UnitArea.squareCentimeters, UnitArea.squareMeters, UnitArea.squareKilometers, UnitArea.squareMegameters, UnitArea.squareInches, UnitArea.squareFeet, UnitArea.squareYards, UnitArea.squareMiles, UnitArea.acres, UnitArea.hectares, UnitArea.ares], [UnitConcentrationMass.gramsPerLiter, UnitConcentrationMass.milligramsPerDeciliter, UnitConcentrationMass.millimolesPerLiter], [UnitDuration.seconds, UnitDuration.minutes, UnitDuration.hours], [UnitElectricCharge.coulombs, UnitElectricCharge.microampereHours, UnitElectricCharge.milliampereHours, UnitElectricCharge.ampereHours, UnitElectricCharge.kiloampereHours, UnitElectricCharge.megaampereHours], [UnitElectricCurrent.microamperes, UnitElectricCurrent.milliamperes, UnitElectricCurrent.amperes, UnitElectricCurrent.kiloamperes, UnitElectricCurrent.megaamperes], [UnitElectricPotentialDifference.microvolts, UnitElectricPotentialDifference.millivolts, UnitElectricPotentialDifference.volts, UnitElectricPotentialDifference.kilovolts, UnitElectricPotentialDifference.megavolts], [UnitElectricResistance.microohms, UnitElectricResistance.milliohms, UnitElectricResistance.ohms, UnitElectricResistance.kiloohms, UnitElectricResistance.megaohms], [UnitEnergy.joules, UnitEnergy.kilojoules, UnitEnergy.calories, UnitEnergy.kilocalories, UnitEnergy.kilowattHours], [UnitFrequency.nanohertz, UnitFrequency.microhertz, UnitFrequency.millihertz, UnitFrequency.hertz, UnitFrequency.kilohertz, UnitFrequency.megahertz, UnitFrequency.gigahertz, UnitFrequency.terahertz], [UnitFuelEfficiency.litersPer100Kilometers, UnitFuelEfficiency.milesPerGallon, UnitFuelEfficiency.milesPerImperialGallon], [UnitLength.picometers, UnitLength.nanometers, UnitLength.micrometers, UnitLength.millimeters, UnitLength.centimeters, UnitLength.decimeters, UnitLength.meters, UnitLength.decameters, UnitLength.hectometers, UnitLength.kilometers, UnitLength.megameters, UnitLength.inches, UnitLength.feet, UnitLength.yards, UnitLength.miles, UnitLength.nauticalMiles, UnitLength.lightyears, UnitLength.astronomicalUnits, UnitLength.fathoms, UnitLength.furlongs, UnitLength.scandinavianMiles], [UnitMass.picograms, UnitMass.nanograms, UnitMass.micrograms, UnitMass.milligrams, UnitMass.centigrams, UnitMass.decigrams, UnitMass.grams, UnitMass.kilograms, UnitMass.metricTons, UnitMass.ounces, UnitMass.pounds, UnitMass.stones, UnitMass.shortTons, UnitMass.carats, UnitMass.ouncesTroy, UnitMass.slugs], [UnitPower.femtowatts, UnitPower.picowatts, UnitPower.nanowatts, UnitPower.microwatts, UnitPower.milliwatts, UnitPower.watts, UnitPower.kilowatts, UnitPower.megawatts, UnitPower.gigawatts, UnitPower.terawatts, UnitPower.horsepower], [UnitPressure.newtonsPerMetersSquared, UnitPressure.hectopascals, UnitPressure.kilopascals, UnitPressure.megapascals, UnitPressure.gigapascals, UnitPressure.millibars, UnitPressure.bars, UnitPressure.poundsForcePerSquareInch, UnitPressure.millimetersOfMercury, UnitPressure.inchesOfMercury], [UnitSpeed.metersPerSecond, UnitSpeed.kilometersPerHour, UnitSpeed.milesPerHour, UnitSpeed.knots], [UnitTemperature.celsius, UnitTemperature.fahrenheit, UnitTemperature.kelvin], [UnitVolume.milliliters, UnitVolume.centiliters, UnitVolume.deciliters, UnitVolume.liters, UnitVolume.kiloliters, UnitVolume.megaliters, UnitVolume.cubicMillimeters, UnitVolume.cubicDecimeters, UnitVolume.cubicMeters, UnitVolume.cubicKilometers, UnitVolume.fluidOunces, UnitVolume.cups, UnitVolume.pints, UnitVolume.quarts, UnitVolume.gallons, UnitVolume.cubicInches, UnitVolume.cubicFeet, UnitVolume.cubicYards, UnitVolume.cubicMiles, UnitVolume.acreFeet, UnitVolume.bushels, UnitVolume.teaspoons, UnitVolume.tablespoons, UnitVolume.imperialTeaspoons, UnitVolume.imperialTablespoons, UnitVolume.imperialFluidOunces, UnitVolume.imperialPints, UnitVolume.imperialQuarts, UnitVolume.imperialGallons, UnitVolume.metricCups]]
    @State private var inputValue:String = ""
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Text("Unit Converter").font(.largeTitle).fontWeight(.semibold)
                Spacer()
                HStack(spacing: 0){
                    VStack {
                        Spacer()
                        TextField("Enter a value", text: self.$inputValue)
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .keyboardType(.decimalPad)
                            .frame(width: geometry.size.width/2.5)
                        Text("\(self.unitsArr[self.unitTypesIndex][self.fromUnitsIndex])")
                            .lineLimit(1)
                            .minimumScaleFactor(0.5)
                            .foregroundColor(.white)
                    }
                    .frame(minWidth: 0, maxWidth: .infinity)
                    Spacer()
                    Text("=")
                        .font(.title)
                        .foregroundColor(.white)
                    Spacer()
                    VStack (spacing: 10){
                        Spacer()
                        Text("\(convert((self.inputValue as NSString).doubleValue, from: UnitAcceleration.metersPerSecondSquared, to: UnitAcceleration.metersPerSecondSquared))")
                            .frame(width: geometry.size.width/2.5)
                            .foregroundColor(.white)
                        Text("\(self.unitsArr[self.unitTypesIndex][self.toUnitsIndex])")
                        .lineLimit(1)
                        .minimumScaleFactor(0.5)
                        .foregroundColor(.white)
                    }
                    .frame(minWidth: 0, maxWidth: .infinity)
                }
                .frame(maxWidth: geometry.size.width/1.15, maxHeight: geometry.size.height/9)
                .padding()
                .background(Color.blue)
                .cornerRadius(25.0)
                Spacer()
                VStack {
                    Text("Unit Type")
                        .fontWeight(.medium)
                        .foregroundColor(.white)
                        .font(.title)
                    Picker(selection: self.$unitTypesIndex, label: Text("Unit Type").foregroundColor(.white)) {
                        ForEach(0..<self.unitTypesArr.count) { index in
                            Text(self.unitTypesArr[index])
                                .foregroundColor(.white)
                                .fontWeight(.semibold)
                                .tag(index)
                        }
                    }
                    .frame(maxHeight: geometry.size.height/9)
                    .clipped()
                    .labelsHidden()
                    .pickerStyle(DefaultPickerStyle())
                }
                .padding()
                .background(Color.blue)
                .cornerRadius(25.0)
                VStack {
                    Text("Convert From")
                        .fontWeight(.medium)
                        .foregroundColor(.white)
                        .font(.title)
                    Picker(selection: self.$fromUnitsIndex, label: Text("Unit Type").foregroundColor(.white)) {
                        ForEach(0..<self.unitsArr[self.unitTypesIndex].count) { index in
                            Text(self.unitsArr[self.unitTypesIndex][index])
                                .foregroundColor(.white)
                                .fontWeight(.semibold)
                                .tag(index)
                        }
                    }
                    .id(self.unitTypesIndex*10+self.fromUnitsIndex)
                    .frame(maxHeight: geometry.size.height/9)
                    .clipped()
                    .labelsHidden()
                    .pickerStyle(DefaultPickerStyle())
                }
                .padding()
                .background(Color.blue)
                .cornerRadius(25.0)
                VStack {
                    Text("Convert To")
                        .fontWeight(.medium)
                        .foregroundColor(.white)
                        .font(.title)
                    Picker(selection: self.$toUnitsIndex, label: Text("Unit Type").foregroundColor(.white)) {
                        ForEach(0..<self.unitsArr[self.unitTypesIndex].count) { index in
                            Text(self.unitsArr[self.unitTypesIndex][index])
                                .foregroundColor(.white)
                                .fontWeight(.semibold)
                                .tag(index)
                        }
                    }
                    .id(self.unitTypesIndex*10+self.toUnitsIndex)
                    .frame(maxHeight: geometry.size.height/9)
                    .clipped()
                    .labelsHidden()
                    .pickerStyle(DefaultPickerStyle())
                }
                .padding()
                .background(Color.blue)
                .cornerRadius(25.0)
                Spacer()
            }
            .padding()
        }
    }
}
func convert(uu值:Double,从sourceUnit:Dimension到targetUnit:Dimension)->Double{
设a=测量值(值:值,单位:源单位)
设b=a.转换为:targetUnit.值
返回b
}
结构ContentView:View{
@国家私有变量fromUnitsIndex:Int=0
@国家私有变量toUnitsIndex:Int=0
@国家私有变量unitTypesIndex:Int=0
专用var unitTypesArr=[“加速度”、“角度”、“面积”、“质量浓度”、“持续时间”、“电荷”、“电流”、“电位差”、“电阻”、“能量”、“频率”、“燃油效率”、“长度”、“质量”、“功率”、“压力”、“速度”、“温度”、“体积”]
私人var单位R=[“米/秒平方”,“重力”],[“度”,“弧度”,“弧分”,“弧秒”,“梯度”,“转数”],[“平方纳米”,“平方微米”,“平方毫米”,“平方厘米”,“平方米”,“平方公里”,“平方米”,“平方英寸”,“平方英尺”,“平方码”,“平方英里”、“英亩”、“公顷”、“Ares”]、[“克每升”、“毫克每分升”、“毫摩尔每升”]、[“秒”、“分”、“小时”]、[“库仑”、“微安时”、“毫安时”、“安时”、“千安时”、“兆安时”]、[“微安”、“毫安”、“安培”、“千安”、“兆安时”]、[”微伏、毫伏、伏特、千伏、兆伏、[“微欧姆”、“毫欧姆”、“欧姆”、“千欧姆”、“兆欧姆”]、[“焦耳”、“千焦耳”、“卡路里”、“千卡路里”、“千瓦时”]、[“纳赫兹”、“毫赫兹”、“赫兹”、“千赫兹”、“兆赫”、“千兆赫兹”、“太赫兹”]、[“每100公里升数”、“每加仑英里数”、”每英制加仑英里数“],[“皮米”、“纳米”、“微米”、“毫米”、“厘米”、“分米”、“米”、“十米”、“百米”、“公里”、“兆米”、“英寸”、“英尺”、“码”、“英里”、“海里”、“光年”、“天文单位”、“帕塞克”、“英寻”、“弗隆”、“斯堪的纳维亚英里”],[“皮克”纳克、微克、毫克、厘米、分克、克、千克、公吨、盎司、磅、石头、短吨、克拉、盎司特洛伊、蛞蝓、[“毫瓦”、“皮瓦”、“纳瓦”、“微瓦”、“毫瓦”、“瓦”、“千瓦”、“兆瓦”、“千兆瓦”、“太瓦”、“马力”]、[“帕斯卡”、”“百帕”、“千帕”、“兆帕”、“千兆帕”、“毫巴”、“巴”、“磅/平方英寸”、“毫米汞”、“英寸汞”]、[“米/秒”、“千米/小时”、“英里/小时”、“节”]、[“摄氏度”、“华氏度”、“开尔文度”]、[“毫升”、“厘米”、“分升”、“升”、”“千升”、“兆升”、“立方毫米”、“立方分米”、“立方米”、“立方公里”、“液体盎司”、“杯子”、“品脱”、“夸脱”、“加仑”、“立方英寸”、“立方英尺”、“立方码”、“立方英里”、“英亩英尺”、“蒲式耳”、“茶匙”、“大汤匙”、“英制茶匙”、“英制液体盎司”英制品脱、英制夸脱、英制加仑、公制杯]]
私有变量convUnitsArr=[[UnitAcceleration.metersPerSecondSquared,UnitAcceleration.gravity],[UnitAngle.degrees,UnitAngle.radians,UnitAngle.arcMinutes,UnitAngle.arcSeconds,UnitAngle.gradians,UnitAngle.revolutions],[UnitArea.平方纳米,UnitArea.平方微米,UnitArea.平方毫米,UnitArea.平方厘米,UnitArea.平方米,UnitArea.平方公里,UnitArea.平方兆米,UnitArea.平方英寸,UnitArea.平方英尺,UnitArea.平方码,UnitArea.平方英里,UnitArea.英亩,UnitArea.公顷,UnitArea.面积],[UnitConcentrationMass.gramsperl,UnitConcentrationMass.milligramsperdecil,UnitConcentrationMass.millimolesperlier],[UnitDuration.seconds,UnitDuration.minutes,UnitDuration.hours],[单位电量.库仑,单位电量.微安时,单位电量.毫安时,单位电量.安培时,单位电量.千安时,单位电量.兆安时],[单位电流.微安,单位电流.毫安,单位电流.安培,单位电流.千安培,单位电流.兆安培],[单位电位差。微伏,单位电位差。毫伏,单位电位差。伏,单位电位差。千伏,单位电位差。兆伏],[单位电阻.微欧姆,单位电阻.毫欧姆,单位电阻.欧姆,单位电阻.千欧姆,单位电阻.兆欧姆],[单位能量.焦耳,单位能量.千焦耳,单位能量.卡路里,单位能量.千卡路里,单位能量.千瓦时],[UnitFrequency.nanohertz,UnitFrequency.microhertz,UnitFrequency.millhertz,UnitFrequency.kighertz,UnitFrequency.meghertz,UnitFrequency.gighertz,UnitFrequency.terahertz],[UnitFuelEfficiency.litersper100km,unitfueleficiency.milesPerGallon,unitfueleficiency.milesPerImperialGallon],[单位长度.皮米,单位长度.纳米,单位长度.微米,单位长度.毫米,单位长度.厘米,单位长度.分米,单位长度.米,单位长度.十米,单位长度.百米,单位长度.公里,单位长度.兆米,单位长度.英寸,单位长度.英尺,单位长度.码,单位长度.英里,单位长度
class UnitViewModel: ObservableObject {

    @Published var fromUnitsIndex: Int = 0
    @Published var toUnitsIndex: Int = 0

    init() {
        fromUnitsIndex = 0
        toUnitsIndex = 0
    }

    @Published var unitTypeIndex: Int = 0 {
        didSet {
            fromUnitsIndex = 0
            toUnitsIndex = 0
        }
    }
}
@ObservedObject var viewModel: UnitViewModel