Commit be813357 by Dmitriy Stepanets

- Finished runtime updates on settings changes

- Started implementing TodayAlertCell
parent 70d4e39e
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F425DE9571009FE398 /* ArrowButton.swift */; }; CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F425DE9571009FE398 /* ArrowButton.swift */; };
CD3F6E6925FA59D4002DB99B /* ForecastDetailPeriodButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3F6E6825FA59D4002DB99B /* ForecastDetailPeriodButton.swift */; }; CD3F6E6925FA59D4002DB99B /* ForecastDetailPeriodButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3F6E6825FA59D4002DB99B /* ForecastDetailPeriodButton.swift */; };
CD3F6E6C25FA5A90002DB99B /* PeriodButtonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3F6E6B25FA5A90002DB99B /* PeriodButtonProtocol.swift */; }; CD3F6E6C25FA5A90002DB99B /* PeriodButtonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3F6E6B25FA5A90002DB99B /* PeriodButtonProtocol.swift */; };
CD4742D0261200500061AC95 /* TodayAlertCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD4742CF261200500061AC95 /* TodayAlertCell.swift */; };
CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */; }; CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */; };
CD593BC926089FC100C93428 /* UITableView+HeaderSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC826089FC100C93428 /* UITableView+HeaderSize.swift */; }; CD593BC926089FC100C93428 /* UITableView+HeaderSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BC826089FC100C93428 /* UITableView+HeaderSize.swift */; };
CD593BCC2608A4F200C93428 /* ForecastDailyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */; }; CD593BCC2608A4F200C93428 /* ForecastDailyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */; };
...@@ -178,6 +179,7 @@ ...@@ -178,6 +179,7 @@
CD39F2F425DE9571009FE398 /* ArrowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowButton.swift; sourceTree = "<group>"; }; CD39F2F425DE9571009FE398 /* ArrowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowButton.swift; sourceTree = "<group>"; };
CD3F6E6825FA59D4002DB99B /* ForecastDetailPeriodButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDetailPeriodButton.swift; sourceTree = "<group>"; }; CD3F6E6825FA59D4002DB99B /* ForecastDetailPeriodButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDetailPeriodButton.swift; sourceTree = "<group>"; };
CD3F6E6B25FA5A90002DB99B /* PeriodButtonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeriodButtonProtocol.swift; sourceTree = "<group>"; }; CD3F6E6B25FA5A90002DB99B /* PeriodButtonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeriodButtonProtocol.swift; sourceTree = "<group>"; };
CD4742CF261200500061AC95 /* TodayAlertCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayAlertCell.swift; sourceTree = "<group>"; };
CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePeriodOffsetHolder.swift; sourceTree = "<group>"; }; CD593BC126088A5900C93428 /* TimePeriodOffsetHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimePeriodOffsetHolder.swift; sourceTree = "<group>"; };
CD593BC826089FC100C93428 /* UITableView+HeaderSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+HeaderSize.swift"; sourceTree = "<group>"; }; CD593BC826089FC100C93428 /* UITableView+HeaderSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+HeaderSize.swift"; sourceTree = "<group>"; };
CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDailyCell.swift; sourceTree = "<group>"; }; CD593BCB2608A4F200C93428 /* ForecastDailyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDailyCell.swift; sourceTree = "<group>"; };
...@@ -521,6 +523,7 @@ ...@@ -521,6 +523,7 @@
CDC6126025E8DA2900188DA7 /* CityMoonCell */, CDC6126025E8DA2900188DA7 /* CityMoonCell */,
CDC6124D25E7960D00188DA7 /* CityDayTimesCell */, CDC6124D25E7960D00188DA7 /* CityDayTimesCell */,
CDC6125525E7AAF600188DA7 /* CityAirQualityCell */, CDC6125525E7AAF600188DA7 /* CityAirQualityCell */,
CD4742CF261200500061AC95 /* TodayAlertCell.swift */,
); );
path = Cells; path = Cells;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -931,6 +934,7 @@ ...@@ -931,6 +934,7 @@
CD866A65260F642600E96A5C /* SettingsDetailsViewController.swift in Sources */, CD866A65260F642600E96A5C /* SettingsDetailsViewController.swift in Sources */,
CD647D0225ED07D60034578B /* TodayViewModel.swift in Sources */, CD647D0225ED07D60034578B /* TodayViewModel.swift in Sources */,
CD593BD32608BC3F00C93428 /* ForecastDayCell.swift in Sources */, CD593BD32608BC3F00C93428 /* ForecastDayCell.swift in Sources */,
CD4742D0261200500061AC95 /* TodayAlertCell.swift in Sources */,
CD15DB4225DA806C00024727 /* CityForecastTimePeriodCell.swift in Sources */, CD15DB4225DA806C00024727 /* CityForecastTimePeriodCell.swift in Sources */,
CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */, CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */,
CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */, CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */,
......
...@@ -12,12 +12,13 @@ import CoreLocation ...@@ -12,12 +12,13 @@ import CoreLocation
class AppDelegate: UIResponder, UIApplicationDelegate { class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ThemeManager.refreshAppearance() ThemeManager.refreshAppearance()
self.window = UIWindow(frame: UIScreen.main.bounds) self.window = UIWindow(frame: UIScreen.main.bounds)
let appCoordinator = AppCoordinator(window: self.window!) let appCoordinator = AppCoordinator(window: self.window!)
appCoordinator.start() appCoordinator.start()
ThemeManager.setBaseTheme()
return true return true
} }
......
...@@ -17,9 +17,5 @@ extension Dimension { ...@@ -17,9 +17,5 @@ extension Dimension {
var name:String { var name:String {
return Dimension.fmt.string(from: self) return Dimension.fmt.string(from: self)
} }
var identifier:String {
return "self."
}
} }
...@@ -12,6 +12,7 @@ extension Measurement { ...@@ -12,6 +12,7 @@ extension Measurement {
let fmt = MeasurementFormatter() let fmt = MeasurementFormatter()
fmt.locale = Settings.shared.locale fmt.locale = Settings.shared.locale
fmt.unitStyle = style fmt.unitStyle = style
fmt.unitOptions = .providedUnit
fmt.numberFormatter.maximumFractionDigits = 0 fmt.numberFormatter.maximumFractionDigits = 0
return fmt return fmt
} }
...@@ -30,7 +31,42 @@ extension Measurement { ...@@ -30,7 +31,42 @@ extension Measurement {
} }
extension Temperature { extension Temperature {
var localizedValue:Double { var settingsConvertedValue:Double {
return self.converted(to: Settings.shared.temperatureType).value.rounded(.down) return self.converted(to: Settings.shared.temperatureType).value.rounded(.down)
} }
var settingsConverted:Measurement {
return self.converted(to: Settings.shared.temperatureType)
}
}
extension WindSpeed {
var settingsConvertedValue:Double {
return self.converted(to: Settings.shared.windSpeedType).value.rounded(.down)
}
var settingsConverted:Measurement {
return self.converted(to: Settings.shared.windSpeedType)
}
}
extension Visibility {
var settingsConvertedValue:Double {
return self.converted(to: Settings.shared.distanceType).value.rounded(.down)
}
var settingsConverted:Measurement {
return self.converted(to: Settings.shared.distanceType)
}
} }
extension Pressure {
var settingsConvertedValue:Double {
return self.converted(to: Settings.shared.pressureType).value.rounded(.down)
}
var settingsConverted:Measurement {
return self.converted(to: Settings.shared.pressureType)
}
}
...@@ -20,7 +20,7 @@ extension UIView { ...@@ -20,7 +20,7 @@ extension UIView {
case .dark: case .dark:
return .dark return .dark
case .system: case .system:
if #available(iOS 12.0, *) { if #available(iOS 13, *) {
return traitCollection.userInterfaceStyle == .light ? .light : .dark return traitCollection.userInterfaceStyle == .light ? .light : .dark
} }
else { else {
......
...@@ -22,13 +22,13 @@ struct UserDefaultsUnitValue<T> { ...@@ -22,13 +22,13 @@ struct UserDefaultsUnitValue<T> {
return decoded return decoded
} }
set { set {
if let data = try? NSKeyedArchiver.archivedData(withRootObject: newValue, requiringSecureCoding: true) {
UserDefaults.standard.set(data, forKey: key) let data = NSKeyedArchiver.archivedData(withRootObject: newValue)
UserDefaults.standard.synchronize() UserDefaults.standard.set(data, forKey: key)
UserDefaults.standard.synchronize()
Settings.shared.delegate.invoke { (delegate) in
delegate.settingsDidChange() Settings.shared.delegate.invoke { (delegate) in
} delegate.settingsDidChange()
} }
} }
} }
...@@ -75,24 +75,45 @@ class Settings { ...@@ -75,24 +75,45 @@ class Settings {
private init() {} private init() {}
@UserDefaultsBasicValue(key: "app_theme") @UserDefaultsBasicValue(key: "app_theme")
var appTheme = AppTheme.system private var _appTheme = AppTheme.system.rawValue
@UserDefaultsBasicValue(key: "app_theme_auto") public var appTheme:AppTheme {
var automaticSwitchTheme = false get {
return AppTheme(rawValue: _appTheme) ?? .system
}
set {
_appTheme = newValue.rawValue
if #available(iOS 13, *) {
switch newValue {
case .light:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .light
case .dark:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .dark
case .system:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .unspecified
}
}
Settings.shared.delegate.invoke { (delegate) in
delegate.settingsDidChange()
}
}
}
@UserDefaultsUnitValue(key: "temperature_type") @UserDefaultsUnitValue(key: "temperature_type")
var temperatureType = UnitTemperature.celsius public var temperatureType = UnitTemperature.celsius
@UserDefaultsUnitValue(key: "wind_speed_type") @UserDefaultsUnitValue(key: "wind_speed_type")
var windSpeedType = UnitSpeed.milesPerHour public var windSpeedType = UnitSpeed.milesPerHour
@UserDefaultsUnitValue(key: "pressure_type") @UserDefaultsUnitValue(key: "pressure_type")
var pressureType = UnitPressure.millibars public var pressureType = UnitPressure.millibars
@UserDefaultsUnitValue(key: "distance_type") @UserDefaultsUnitValue(key: "distance_type")
var distanceType = UnitLength.miles public var distanceType = UnitLength.miles
var locale:Locale { public var locale:Locale {
return Locale(identifier: Localize.currentLanguage()) return Locale(identifier: Localize.currentLanguage())
} }
} }
...@@ -110,8 +110,8 @@ class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -110,8 +110,8 @@ class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol {
weatherImageView.image = dailyWeather.type.image(isDay: true) weatherImageView.image = dailyWeather.type.image(isDay: true)
weatherTypeLabel.text = dailyWeather.type.localized(isDay: true) weatherTypeLabel.text = dailyWeather.type.localized(isDay: true)
maxTempLabel.text = dailyWeather.maxTemp?.shortString maxTempLabel.text = dailyWeather.maxTemp?.settingsConverted.shortString
minTempLabel.text = dailyWeather.minTemp?.shortString minTempLabel.text = dailyWeather.minTemp?.settingsConverted.shortString
let percent = dailyWeather.precipitationProbability ?? 0 let percent = dailyWeather.precipitationProbability ?? 0
precipLabel.text = "\(percent)%" precipLabel.text = "\(percent)%"
......
...@@ -110,8 +110,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -110,8 +110,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
//Public //Public
func configure(dailyWeather: DailyWeather) { func configure(dailyWeather: DailyWeather) {
self.tempLabel.text = dailyWeather.maxTemp?.shortString self.tempLabel.text = dailyWeather.maxTemp?.settingsConverted.shortString
self.minTempLabel.text = dailyWeather.minTemp?.shortString self.minTempLabel.text = dailyWeather.minTemp?.settingsConverted.shortString
self.indicatorImageView.image = nil self.indicatorImageView.image = nil
self.forecastImageView.image = dailyWeather.type.image(isDay: true) self.forecastImageView.image = dailyWeather.type.image(isDay: true)
if Calendar.timeZoneCalendar(timeZone: dailyWeather.timeZone).isDateInToday(dailyWeather.date) { if Calendar.timeZoneCalendar(timeZone: dailyWeather.timeZone).isDateInToday(dailyWeather.date) {
...@@ -124,7 +124,7 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -124,7 +124,7 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
} }
func configure(hourlyWeather: HourlyWeather) { func configure(hourlyWeather: HourlyWeather) {
self.tempLabel.text = hourlyWeather.temp?.shortString self.tempLabel.text = hourlyWeather.temp?.settingsConverted.shortString
self.minTempLabel.text = nil self.minTempLabel.text = nil
self.indicatorImageView.image = nil self.indicatorImageView.image = nil
if Calendar.isNow(fromDate: hourlyWeather.date, timeZone: hourlyWeather.timeZone) { if Calendar.isNow(fromDate: hourlyWeather.date, timeZone: hourlyWeather.timeZone) {
......
...@@ -163,9 +163,9 @@ class ForecastTimePeriodView: UIView { ...@@ -163,9 +163,9 @@ class ForecastTimePeriodView: UIView {
private func updateDailyGraphPoints() { private func updateDailyGraphPoints() {
let daysCount = daily.count let daysCount = daily.count
let maxTemps = (daily.map{ CGFloat($0.maxTemp?.localizedValue ?? 0) }) let maxTemps = (daily.map{ CGFloat($0.maxTemp?.settingsConvertedValue ?? 0) })
let topMaxTemp = maxTemps.max() ?? 0 let topMaxTemp = maxTemps.max() ?? 0
let minTemps = (daily.map{ CGFloat($0.minTemp?.localizedValue ?? 0) }) let minTemps = (daily.map{ CGFloat($0.minTemp?.settingsConvertedValue ?? 0) })
let topMinTemp = minTemps.max() ?? 0 let topMinTemp = minTemps.max() ?? 0
var maxPoints = [CGPoint]() var maxPoints = [CGPoint]()
...@@ -201,7 +201,7 @@ class ForecastTimePeriodView: UIView { ...@@ -201,7 +201,7 @@ class ForecastTimePeriodView: UIView {
private func updateHourlyGraphPoints() { private func updateHourlyGraphPoints() {
let hoursCount = hourly.count let hoursCount = hourly.count
let temps = (hourly.map{ CGFloat($0.temp?.localizedValue ?? 0) }) let temps = (hourly.map{ CGFloat($0.temp?.settingsConvertedValue ?? 0) })
let maxTemp = temps.max() ?? 0 let maxTemp = temps.max() ?? 0
var points = [CGPoint]() var points = [CGPoint]()
......
...@@ -104,7 +104,7 @@ class ForecastWindButton: UIControl, PeriodButtonProtocol { ...@@ -104,7 +104,7 @@ class ForecastWindButton: UIControl, PeriodButtonProtocol {
func configure(hourlyWeather: HourlyWeather) { func configure(hourlyWeather: HourlyWeather) {
let direction = hourlyWeather.windDirection?.rawValue ?? "--" let direction = hourlyWeather.windDirection?.rawValue ?? "--"
let speed = hourlyWeather.windSpeed?.string ?? "--" let speed = hourlyWeather.windSpeed?.settingsConverted.string ?? "--"
windInfoLabel.text = "\(direction.uppercased())\n\(speed.uppercased())" windInfoLabel.text = "\(direction.uppercased())\n\(speed.uppercased())"
let degrees = hourlyWeather.windDirection?.degrees ?? 0 let degrees = hourlyWeather.windDirection?.degrees ?? 0
directionImageView.transform = CGAffineTransform(rotationAngle: degrees * .pi / 180) directionImageView.transform = CGAffineTransform(rotationAngle: degrees * .pi / 180)
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
import UIKit import UIKit
public enum AppTheme { public enum AppTheme: Int {
case light case light = 0
case dark case dark
case system case system
} }
...@@ -27,6 +27,19 @@ public struct ThemeManager { ...@@ -27,6 +27,19 @@ public struct ThemeManager {
return DefaultTheme() return DefaultTheme()
} }
static func setBaseTheme() {
if #available(iOS 13, *) {
switch Settings.shared.appTheme {
case .light:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .light
case .dark:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .dark
case .system:
UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .unspecified
}
}
}
static func refreshAppearance() { static func refreshAppearance() {
//Navigation bar //Navigation bar
UINavigationBar.appearance().barTintColor = currentTheme.navigationBarBackgroundColor UINavigationBar.appearance().barTintColor = currentTheme.navigationBarBackgroundColor
......
...@@ -50,8 +50,8 @@ class ForecastDayCell: UITableViewCell { ...@@ -50,8 +50,8 @@ class ForecastDayCell: UITableViewCell {
public func configure(today:CurrentWeather) { public func configure(today:CurrentWeather) {
ForecastDayCell.formatter.timeZone = today.timeZone ForecastDayCell.formatter.timeZone = today.timeZone
dateLabel.text = ForecastDayCell.formatter.string(from: today.date) dateLabel.text = ForecastDayCell.formatter.string(from: today.date)
let maxTemp = today.maxTemp?.shortString ?? "--" let maxTemp = today.maxTemp?.settingsConverted.shortString ?? "--"
let minTemp = today.minTemp?.shortString ?? "--" let minTemp = today.minTemp?.settingsConverted.shortString ?? "--"
forecastLabel.text = "\(today.type.localized(isDay: today.isDay)) | \(maxTemp)/\(minTemp)" forecastLabel.text = "\(today.type.localized(isDay: today.isDay)) | \(maxTemp)/\(minTemp)"
} }
} }
......
...@@ -37,7 +37,7 @@ class ForecastConditionView: UIView { ...@@ -37,7 +37,7 @@ class ForecastConditionView: UIView {
case .visibility: case .visibility:
valueLabel.text = "--" valueLabel.text = "--"
case .wind: case .wind:
let speed = dailyWeather.windSpeed?.string ?? "--" let speed = dailyWeather.windSpeed?.settingsConverted.string ?? "--"
let direction = dailyWeather.windDirection?.rawValue ?? "" let direction = dailyWeather.windDirection?.rawValue ?? ""
valueLabel.text = "\(direction) \(speed)" valueLabel.text = "\(direction) \(speed)"
} }
......
...@@ -47,8 +47,8 @@ class ForecastInfoCell: UITableViewCell { ...@@ -47,8 +47,8 @@ class ForecastInfoCell: UITableViewCell {
//Public //Public
public func configure(dailyWeather: DailyWeather) { public func configure(dailyWeather: DailyWeather) {
weatherTypeImageView.image = dailyWeather.type.image(isDay: true) weatherTypeImageView.image = dailyWeather.type.image(isDay: true)
let maxTemp = dailyWeather.maxTemp?.shortString ?? "--" let maxTemp = dailyWeather.maxTemp?.settingsConverted.shortString ?? "--"
let minTemp = dailyWeather.minTemp?.shortString ?? "--" let minTemp = dailyWeather.minTemp?.settingsConverted.shortString ?? "--"
tempLabel.text = "\(maxTemp)/\(minTemp)" tempLabel.text = "\(maxTemp)/\(minTemp)"
weatherTypeLabel.text = dailyWeather.type.localized(isDay: true) weatherTypeLabel.text = dailyWeather.type.localized(isDay: true)
weatherDescriptionLabel.text = "Feels like --" weatherDescriptionLabel.text = "Feels like --"
......
...@@ -85,11 +85,19 @@ private struct SettingsDataSource { ...@@ -85,11 +85,19 @@ private struct SettingsDataSource {
class SettingsCellFactory: CellFactoryProtocol { class SettingsCellFactory: CellFactoryProtocol {
//Private //Private
private let viewModel:SettingsViewModel private let viewModel:SettingsViewModel
private let sections:[SettingsDataSource] = [SettingsDataSource(section: .theme, rows: [.theme]), private let sections:[SettingsDataSource] = {
SettingsDataSource(section: .units, rows: [.temperature, .wind, .pressure, .distance]), var array = [SettingsDataSource]()
SettingsDataSource(section: .language, rows: [.language]),
SettingsDataSource(section: .other, rows: [.manageNotifications, .locationAccess])] if #available(iOS 13, *) {
array.append(SettingsDataSource(section: .theme, rows: [.theme]))
}
array.append(contentsOf: [SettingsDataSource(section: .units, rows: [.temperature, .wind, .pressure, .distance]),
SettingsDataSource(section: .language, rows: [.language]),
SettingsDataSource(section: .other, rows: [.manageNotifications, .locationAccess])])
return array
}()
//Public //Public
init(viewModel:SettingsViewModel) { init(viewModel:SettingsViewModel) {
self.viewModel = viewModel self.viewModel = viewModel
......
...@@ -51,6 +51,7 @@ class SettingsThemeCell: UITableViewCell { ...@@ -51,6 +51,7 @@ class SettingsThemeCell: UITableViewCell {
private func updateUI() { private func updateUI() {
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
configure(settings: Settings.shared)
switch interfaceStyle { switch interfaceStyle {
case .light: case .light:
...@@ -65,18 +66,25 @@ class SettingsThemeCell: UITableViewCell { ...@@ -65,18 +66,25 @@ class SettingsThemeCell: UITableViewCell {
} }
@objc private func handleThemeButton(button: UIButton) { @objc private func handleThemeButton(button: UIButton) {
switch button {
case lightThemeButton:
Settings.shared.appTheme = .light
case darkThemeButton:
Settings.shared.appTheme = .dark
default:
break
}
} }
@objc private func handleAutomaticSwith() { @objc private func handleAutomaticSwith() {
Settings.shared.appTheme = .system
} }
//Public //Public
public func configure(settings: Settings) { public func configure(settings: Settings) {
lightThemeButton.setImage(interfaceStyle == .light ? checkmarkSelectedImage : checkmarkUnselectedImage, for: .normal) lightThemeButton.setImage(interfaceStyle == .light ? checkmarkSelectedImage : checkmarkUnselectedImage, for: .normal)
darkThemeButton.setImage(interfaceStyle == .dark ? checkmarkSelectedImage : checkmarkUnselectedImage, for: .normal) darkThemeButton.setImage(interfaceStyle == .dark ? checkmarkSelectedImage : checkmarkUnselectedImage, for: .normal)
automaticSwitchButton.isOn = settings.automaticSwitchTheme automaticSwitchButton.isOn = settings.appTheme == .system
} }
} }
......
...@@ -86,6 +86,7 @@ extension SettingsDetailsViewController: UITableViewDelegate { ...@@ -86,6 +86,7 @@ extension SettingsDetailsViewController: UITableViewDelegate {
} }
} }
//MARK:- ViewModel Delegate
extension SettingsDetailsViewController: ViewModelDelegate { extension SettingsDetailsViewController: ViewModelDelegate {
func viewModelDidChange<P>(model: P) where P : ViewModelProtocol { func viewModelDidChange<P>(model: P) where P : ViewModelProtocol {
tableView.reloadData() tableView.reloadData()
......
...@@ -150,6 +150,8 @@ extension SettingsViewController: UITableViewDelegate { ...@@ -150,6 +150,8 @@ extension SettingsViewController: UITableViewDelegate {
} }
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let sectionType = settingsCellFactory.sectionTypeAt(indexPath: indexPath)
guard sectionType == .units else { return }
coordinator.openDetailsViewController(rowType: settingsCellFactory.rowTypeAt(indexPath: indexPath)) coordinator.openDetailsViewController(rowType: settingsCellFactory.rowTypeAt(indexPath: indexPath))
} }
} }
...@@ -33,13 +33,13 @@ class CityConditionButton: UIControl { ...@@ -33,13 +33,13 @@ class CityConditionButton: UIControl {
case .uvIndex: case .uvIndex:
valueLabel.text = "4" valueLabel.text = "4"
case .pressure: case .pressure:
valueLabel.text = location.today?.pressure?.string valueLabel.text = location.today?.pressure?.settingsConverted.string
case .dewPoint: case .dewPoint:
valueLabel.text = "12°" valueLabel.text = "12°"
case .visibility: case .visibility:
valueLabel.text = location.today?.visibility?.string valueLabel.text = location.today?.visibility?.settingsConverted.string
case .wind: case .wind:
let speed = location.today?.windSpeed?.string ?? "--" let speed = location.today?.windSpeed?.settingsConverted.string ?? "--"
let direction = location.today?.windDirection?.rawValue ?? "" let direction = location.today?.windDirection?.rawValue ?? ""
valueLabel.text = "\(direction) \(speed)" valueLabel.text = "\(direction) \(speed)"
} }
......
...@@ -38,7 +38,7 @@ class DayTimeView: UIView { ...@@ -38,7 +38,7 @@ class DayTimeView: UIView {
public func configure(with dayTimeWeather:DayTimeWeather) { public func configure(with dayTimeWeather:DayTimeWeather) {
dayTimeLabel.text = dayTimeWeather.dayTime.localized dayTimeLabel.text = dayTimeWeather.dayTime.localized
forecastImageView.image = dayTimeWeather.type.image(isDay: dayTimeWeather.isDay) forecastImageView.image = dayTimeWeather.type.image(isDay: dayTimeWeather.isDay)
tempLabel.text = dayTimeWeather.temp?.shortString ?? "--" tempLabel.text = dayTimeWeather.temp?.settingsConverted.shortString ?? "--"
dayTimeConditionLabel.text = dayTimeWeather.type.localized(isDay: dayTimeWeather.isDay) dayTimeConditionLabel.text = dayTimeWeather.type.localized(isDay: dayTimeWeather.isDay)
} }
......
...@@ -42,10 +42,10 @@ class CityForecastCell: UITableViewCell { ...@@ -42,10 +42,10 @@ class CityForecastCell: UITableViewCell {
//Public //Public
public func configure(with location:Location) { public func configure(with location:Location) {
cityImageView.image = UIImage(named: location.imageName ?? "") cityImageView.image = UIImage(named: location.imageName ?? "")
temperatureLabel.text = location.today?.temp?.shortString temperatureLabel.text = location.today?.temp?.settingsConverted.shortString
let maxTemp = location.today?.maxTemp?.shortString ?? "--" let maxTemp = location.today?.maxTemp?.settingsConverted.shortString ?? "--"
let minTemp = location.today?.minTemp?.shortString ?? "--" let minTemp = location.today?.minTemp?.settingsConverted.shortString ?? "--"
let feelstemp = location.today?.apparentTemp?.shortString ?? "--" let feelstemp = location.today?.apparentTemp?.settingsConverted.shortString ?? "--"
forecastDescriptionLabel.text = "\(location.today?.type.localized(isDay: location.today?.isDay ?? true) ?? "") | \(maxTemp)/\(minTemp)" forecastDescriptionLabel.text = "\(location.today?.type.localized(isDay: location.today?.isDay ?? true) ?? "") | \(maxTemp)/\(minTemp)"
feelsLikeLabel.text = "Feels like \(feelstemp) - Due to high humidity" feelsLikeLabel.text = "Feels like \(feelstemp) - Due to high humidity"
forecastImageView.image = location.today?.type.image(isDay: location.today?.isDay ?? true) forecastImageView.image = location.today?.type.image(isDay: location.today?.isDay ?? true)
......
//
// TodayAlertCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 29.03.2021.
//
import UIKit
class TodayAlertCell: UITableViewCell {
//Private
private let container = UIView()
private let alertImageView = UIImageView()
private let infoLabel = UILabel()
private let timeAgoLabel = UILabel()
private let moreLabel = UILabel()
}
...@@ -46,8 +46,13 @@ class SettingsDetailsViewModel: ViewModelProtocol { ...@@ -46,8 +46,13 @@ class SettingsDetailsViewModel: ViewModelProtocol {
return Localize.availableLanguages().firstIndex{ $0 == Localize.currentLanguage() } ?? -1 return Localize.availableLanguages().firstIndex{ $0 == Localize.currentLanguage() } ?? -1
} }
deinit {
Settings.shared.delegate.remove(delegate: self)
}
init(rowType: SettingsRow) { init(rowType: SettingsRow) {
self.rowType = rowType self.rowType = rowType
Settings.shared.delegate.add(delegate: self)
} }
public func selectUnitAtIndex(index: Int) { public func selectUnitAtIndex(index: Int) {
...@@ -59,7 +64,7 @@ class SettingsDetailsViewModel: ViewModelProtocol { ...@@ -59,7 +64,7 @@ class SettingsDetailsViewModel: ViewModelProtocol {
case .pressure: case .pressure:
Settings.shared.pressureType = pressures[index] Settings.shared.pressureType = pressures[index]
case .distance: case .distance:
Settings.shared.distanceType = distances[index] Settings.shared.distanceType = distances[index]
default: default:
break break
} }
...@@ -67,7 +72,14 @@ class SettingsDetailsViewModel: ViewModelProtocol { ...@@ -67,7 +72,14 @@ class SettingsDetailsViewModel: ViewModelProtocol {
delegate?.viewModelDidChange(model: self) delegate?.viewModelDidChange(model: self)
} }
public func selectLaanguage(identifier:String, atIndex index:Int) { public func selectLanguage(identifier:String, atIndex index:Int) {
} }
} }
//MARK:- SettingsDetails View Model
extension SettingsDetailsViewModel: SettingsDelegate {
func settingsDidChange() {
self.delegate?.viewModelDidChange(model: self)
}
}
...@@ -18,11 +18,13 @@ class TodayViewModel: ViewModelProtocol { ...@@ -18,11 +18,13 @@ class TodayViewModel: ViewModelProtocol {
deinit { deinit {
self.locationManager.remove(delegate: self) self.locationManager.remove(delegate: self)
Settings.shared.delegate.remove(delegate: self)
} }
public init(locationManager: LocationManager) { public init(locationManager: LocationManager) {
self.locationManager = locationManager self.locationManager = locationManager
locationManager.add(delegate: self) locationManager.add(delegate: self)
Settings.shared.delegate.add(delegate: self)
//Setup factory callback //Setup factory callback
todayCellFactory.onGetLocation = {[weak self] in todayCellFactory.onGetLocation = {[weak self] in
...@@ -45,3 +47,10 @@ extension TodayViewModel: LocationManagerDelegate { ...@@ -45,3 +47,10 @@ extension TodayViewModel: LocationManagerDelegate {
} }
} }
} }
//MARK:- Settings View Model
extension TodayViewModel: SettingsDelegate {
func settingsDidChange() {
delegate?.viewModelDidChange(model: self)
}
}
import Foundation import Foundation
import UIKit import UIKit
let testData = try NSKeyedArchiver.archivedData(withRootObject: UnitTemperature.celsius, requiringSecureCoding: true) let far = Measurement<UnitTemperature>(value: 50, unit: .fahrenheit)
let fmt = MeasurementFormatter()
fmt.unitStyle = .long
fmt.unitOptions = .providedUnit
fmt.string(from: far.converted(to: .kelvin))
...@@ -40,14 +40,14 @@ ...@@ -40,14 +40,14 @@
<key>isShown</key> <key>isShown</key>
<false/> <false/>
<key>orderHint</key> <key>orderHint</key>
<integer>1</integer> <integer>2</integer>
</dict> </dict>
<key>SnapKit.xcscheme</key> <key>SnapKit.xcscheme</key>
<dict> <dict>
<key>isShown</key> <key>isShown</key>
<false/> <false/>
<key>orderHint</key> <key>orderHint</key>
<integer>2</integer> <integer>3</integer>
</dict> </dict>
<key>XMLCoder.xcscheme_^#shared#^_</key> <key>XMLCoder.xcscheme_^#shared#^_</key>
<dict> <dict>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment