@state property
와 값을 받을 textfield
, 단위를 입력받을 segmented control
2개, 그리고 결과 산출 textview
를 구현하면 된다고 되어있다!일단 단위는 부피를 해보기로 결정했다...이유는 그나마 먹는 거랑 관련된 단위인 거 같아서ㅋㅎㅋㅎㅋㅎㅋㅎ...인터페이스 구현은 WeSplit
을 하면서 배운걸 고대로 하면 된다고 생각했고
핵심은 단위 변환
을 어떻게 하느냐 라고 생각했다!그냥 하드코딩을 해도 된다고 했지만 twostraws가 내장함수를 이용해 단위변환 하는 방법을 올려둔 만큼 이를 활용해 보기로 했다
값은 TextField
로 값 자체를 받아 VolumeAmount
에 저장하고, 입출력단위는 Picker
로 인덱스를 받아서 각각 inputUnitIndex
, outputUnitIndex
에 저장한 뒤, 단위 배열에 인덱스로 접근하는 방식으로 구상했다
@State private var inputNumber = ""
@State private var inputUnitIdx = 0
@State private var outputUnitIdx = 0
Measurement(value: Double, unit: Unit)
구조체를 이용해 바로 단위만 나타낼 수 있을 줄 알고 입출력 단위를 받는 부분에서 Measurement 오브젝트
들을 담고 있는 unitConvert
배열에 접근하게 해서 inputUnit
, outputUnit
에 Measurment 오브젝트
를 바로 저장하게 했는데
단위만 출력하는 게 불가능해서 단위 이름을 담은 문자열 배열
units
를 따로 선언해서 인터페이스에는 해당 배열에 접근해 단위만 출력되도록 했다
나중에 변환값을 연산하는 프로퍼티를 만들면서 헷갈리기도 하고 바꾼 이름이 더 적합하다고 생각해 바꿔줬다
let units = ["mL", "L", "cup", "gal"]
let unitVolume = [UnitVolume.milliliters, .liters, .cups, .gallons]
...
Section(header: Text("Input Unit")) {
Picker(selection: $inputUnitIdx, label: Text("Input Unit")) {
ForEach(0 ..< units.count) {
Text("\(self.units[$0])")
}
}
.pickerStyle(SegmentedPickerStyle())
}
Measurement(value: Double, unit: Unit)
구조체를 선언하기 위해 inputUnitIdx
, outputUnitIdx
를 활용해 unitVolume
배열에서 입력받은 단위와 일치하는 UnitVolume
을 inputVolume
과 outputVolume
에 저장하고
inputVolume
을 Measurement 구조체
의 오브젝트로 선언한 뒤
converted 메서드
를 사용해서 변환된 값을 outputVolume
에 할당하고 이를 리턴해서 convertedNumber
에 저장했다
지금와서 보니 convertedNumber
의 타입을 Double
로 선언하고 outputVolume.value
를 리턴했어도 될 것 같다
var convertedNumber : Measurement<UnitVolume> {
let volumeAmount = Double(inputNumber) ?? 0
let inputUnit = unitVolume[inputUnitIdx] // 1번 과정
let outputUnit = unitVolume[outputUnitIdx] // 1번 과정
let inputVolume = Measurement(value: volumeAmount, unit: inputUnit) // 2번 과정
let outputVolume = inputVolume.converted(to: outputUnit) // 3번 과정
return outputVolume
}
처음에는 별 생각없이 Text("\(convertedNumber)")
로 출력했는데 소수점 밑 자리를 자르려고 했더니 위의 방식으로는 바로 고칠 수가 없었다
convertedNumber.value
, convertedNumber.unit
으로 나눠서 출력해보려고 했는데 후자의 경우 단위만 출력되는 게 아니고 타입이 같이 출력됐다
결국 값은 converteNumber.value
를 이용해서 출력하고, 타입은 Picker
에서와 같이 unit
배열을 통해 해결했다
Section(header: Text("Result")) {
Text("\(convertedNumber.value, specifier: "%.2f") \(self.units[outputUnitIdx])")
}
Picker
로 사용자로부터 입력을 받을 때 ForEach
를 통해 단순히 숫자를 입력받더라도 배열
을 활용해 다양한 결과를 산출할 수 있다UnitVolume
타입들을 저장하고 입력값에 따라 입력된 타입을 불러와 별도의 변수에 저장해 다른 타입의 오브젝트 선언에 활용할 수 있다