SettingsManager
)SettingsManager
는 온도 변환 및 사용자 설정값을 관리한다.
온도 변환 공식은 태어나서 처음 봣는데 아래와 같다.
코드
static func convertTemperature(value: Double, to unit: TempUnit) -> Double {
switch unit {
case .celsius:
return (value - 32) * 5.0 / 9.0
case .fahrenheit:
return (value * 9.0 / 5.0) + 32
}
}
그리고 UserDefaults
를 이용해 사용자의 온도 단위 선택값을 저장/불러오는 기능을 제공할 수 있다.
static func saveTempUnit(_ unit: TempUnit) {
UserDefaults.standard.set(unit.rawValue, forKey: tempUnitKey)
}
static func getTempUnit() -> TempUnit {
let value = UserDefaults.standard.string(forKey: tempUnitKey) ?? TempUnit.celsius.rawValue
return TempUnit(rawValue: value) ?? .celsius
}
WeatherViewController
)WeatherViewController
에서는 UIMenu
를 활용해 설정 메뉴를 구현해주고
메뉴에서 단위를 선택하면 Bool값을 이용해 isCelsius
상태가 변경되도록 했다.
이 방법으로 하기 전에 너무 복잡한 방식으로 해서 2시간을 날렸다.
진작 이 방법으로 할 걸
private func createSettingsMenu() -> UIMenu {
let celsiusAction = UIAction(
title: "섭씨",
image: UIImage(systemName: "degreesign.celsius"),
state: isCelsius ? .on : .off
) { [weak self] _ in
self?.isCelsius = true
}
let fahrenheitAction = UIAction(
title: "화씨",
image: UIImage(systemName: "degreesign.fahrenheit"),
state: isCelsius ? .off : .on
) { [weak self] _ in
self?.isCelsius = false
}
return UIMenu(title: "온도 설정", children: [celsiusAction, fahrenheitAction])
}
그리고 단위 전환 시 UI 업데이트를 보장하기 위해 updateTemperatureUnit
메서드를 호출해줘야한다.
private func updateTemperatureUnit() {
updateMenu() // 메뉴 상태 업데이트
for cell in pageCollectionView.visibleCells {
if let weatherCell = cell as? WeatherPageCell {
weatherCell.weatherView.updateTemperatureUnit(isCelsius: isCelsius)
}
}
}
WeatherView
)WeatherView
는 온도 데이터를 표시하고 섭씨/화씨 전환 시 UI를 업데이트해준다.
public func updateTemperatureUnit(isCelsius: Bool) {
let targetUnit: TempUnit = isCelsius ? .celsius : .fahrenheit
if let currentTempText = temperatureLabel.text?.dropLast(),
let currentTempValue = Double(currentTempText) {
let convertedCurrent = SettingsManager.convertTemperature(value: currentTempValue, to: targetUnit)
temperatureLabel.text = "\(Int(convertedCurrent))°"
}
}
private var originalTemperature: Double = 0.0
func setOriginalTemperature(_ temperature: Double) {
originalTemperature = temperature
updateTemperatureUnit(isCelsius: true)
}
updateMenu
와 updateTemperatureUnit
호출했다.private var isCelsius: Bool = true {
didSet {
UserDefaults.standard.set(isCelsius, forKey: "isCelsius")
updateTemperatureUnit()
}
}
UserDefaults
에서 값을 불러와서 초기화를 진행했다.private var isCelsius: Bool = UserDefaults.standard.object(forKey: "isCelsius") as? Bool ?? true
이번 작업에서 원본 데이터 관리의 중요성을 좀 알게 됐다. UI에 표시된 값을 기반으로 로직을 처리하면 데이터 손실이 발생할 수 있다는 점과 UserDefaults
를 통해 사용자 설정을 유지는 방법이라던지, 그리고 UIMenu를 활용하면서 사용자 경험을 개선하기 위해 인터페이스에 적절한 메뉴를 제공하는 방법같은 걸 공부할 수 잇었다.