Commit 41e13440 by Dmitriy Stepanets

- Finished ForecastDetailsButton

- Changed YYYY to yyyy in date formatters
parents b843a0d1 073eda93
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303D25726960004B34B3 /* ThemeProtocol.swift */; }; CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303D25726960004B34B3 /* ThemeProtocol.swift */; };
CD6B304325726AD1004B34B3 /* DefaultTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B304225726AD1004B34B3 /* DefaultTheme.swift */; }; CD6B304325726AD1004B34B3 /* DefaultTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B304225726AD1004B34B3 /* DefaultTheme.swift */; };
CD71709025FA317700A63C27 /* ForecastTimePeriodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */; }; CD71709025FA317700A63C27 /* ForecastTimePeriodView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */; };
CD71709325FA31C200A63C27 /* ForecastTimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD71709225FA31C200A63C27 /* ForecastTimePeriod.swift */; };
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */; }; CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */; };
CD822FF525D6817000A05501 /* CityForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FF425D6817000A05501 /* CityForecastCell.swift */; }; CD822FF525D6817000A05501 /* CityForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FF425D6817000A05501 /* CityForecastCell.swift */; };
CD822FFA25D6890900A05501 /* OneWeatherColorsAsset.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */; }; CD822FFA25D6890900A05501 /* OneWeatherColorsAsset.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */; };
...@@ -120,7 +119,6 @@ ...@@ -120,7 +119,6 @@
CD6B303D25726960004B34B3 /* ThemeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeProtocol.swift; sourceTree = "<group>"; }; CD6B303D25726960004B34B3 /* ThemeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeProtocol.swift; sourceTree = "<group>"; };
CD6B304225726AD1004B34B3 /* DefaultTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTheme.swift; sourceTree = "<group>"; }; CD6B304225726AD1004B34B3 /* DefaultTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTheme.swift; sourceTree = "<group>"; };
CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastTimePeriodView.swift; sourceTree = "<group>"; }; CD71708F25FA317700A63C27 /* ForecastTimePeriodView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastTimePeriodView.swift; sourceTree = "<group>"; };
CD71709225FA31C200A63C27 /* ForecastTimePeriod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastTimePeriod.swift; sourceTree = "<group>"; };
CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = "<group>"; }; CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = "<group>"; };
CD822FF425D6817000A05501 /* CityForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityForecastCell.swift; sourceTree = "<group>"; }; CD822FF425D6817000A05501 /* CityForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityForecastCell.swift; sourceTree = "<group>"; };
CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = OneWeatherColorsAsset.xcassets; sourceTree = "<group>"; }; CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = OneWeatherColorsAsset.xcassets; sourceTree = "<group>"; };
...@@ -519,7 +517,6 @@ ...@@ -519,7 +517,6 @@
CEAFF08B25DFC6BC00DF4EBF /* DailyWeather.swift */, CEAFF08B25DFC6BC00DF4EBF /* DailyWeather.swift */,
CEAFF08E25DFC6ED00DF4EBF /* HourlyWeather.swift */, CEAFF08E25DFC6ED00DF4EBF /* HourlyWeather.swift */,
CE578FD225F7E89400E8B85D /* DayTimeWeather.swift */, CE578FD225F7E89400E8B85D /* DayTimeWeather.swift */,
CD71709225FA31C200A63C27 /* ForecastTimePeriod.swift */,
); );
path = ModelObjects; path = ModelObjects;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -705,7 +702,6 @@ ...@@ -705,7 +702,6 @@
CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */, CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */,
CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */, CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */,
CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */, CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */,
CD71709325FA31C200A63C27 /* ForecastTimePeriod.swift in Sources */,
CEDE4E8325EEFD56007457E9 /* WdtLocationResponse.swift in Sources */, CEDE4E8325EEFD56007457E9 /* WdtLocationResponse.swift in Sources */,
CD8E041625F8F91B001785B6 /* ForecastCellFactory.swift in Sources */, CD8E041625F8F91B001785B6 /* ForecastCellFactory.swift in Sources */,
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */, CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<key>1Weather.xcscheme_^#shared#^_</key> <key>1Weather.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>6</integer> <integer>5</integer>
</dict> </dict>
<key>PG (Playground) 1.xcscheme</key> <key>PG (Playground) 1.xcscheme</key>
<dict> <dict>
......
//
// ForecastTimePeriod.swift
// 1Weather
//
// Created by Dmitry Stepanets on 11.03.2021.
//
import UIKit
struct ForecastTimePeriod {
let daily:[DailyWeather]
let hourly:[HourlyWeather]
}
...@@ -14,7 +14,7 @@ struct WdtDailySummariesArray: Codable { ...@@ -14,7 +14,7 @@ struct WdtDailySummariesArray: Codable {
private static let dateFormatter:DateFormatter = { private static let dateFormatter:DateFormatter = {
let fmt = DateFormatter() let fmt = DateFormatter()
fmt.timeZone = TimeZone(abbreviation: "PST") fmt.timeZone = TimeZone(abbreviation: "PST")
fmt.dateFormat = "MM/dd/YYYY" fmt.dateFormat = "MM/dd/yyyy"
return fmt return fmt
}() }()
......
...@@ -13,7 +13,7 @@ struct WdtHourlySummariesArray: Codable { ...@@ -13,7 +13,7 @@ struct WdtHourlySummariesArray: Codable {
private static let dateFormatter:DateFormatter = { private static let dateFormatter:DateFormatter = {
let fmt = DateFormatter() let fmt = DateFormatter()
fmt.timeZone = TimeZone(abbreviation: "PST") fmt.timeZone = TimeZone(abbreviation: "PST")
fmt.dateFormat = "YYYY-MM-dd HH:mm:ss" fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
return fmt return fmt
}() }()
......
...@@ -46,7 +46,7 @@ struct WdtDailySummary: Codable { ...@@ -46,7 +46,7 @@ struct WdtDailySummary: Codable {
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> DailyWeather? { public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> DailyWeather? {
let log = WdtDailySummary.log let log = WdtDailySummary.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/YYYY" dateFormatter.dateFormat = "MM/dd/yyyy"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: dateLocal) else { guard let date = dateFormatter.date(from: dateLocal) else {
log.error("Failed to parse date from: \(dateLocal)") log.error("Failed to parse date from: \(dateLocal)")
...@@ -80,7 +80,7 @@ struct WdtDailySummary: Codable { ...@@ -80,7 +80,7 @@ struct WdtDailySummary: Codable {
let sunMoonDateFormatter = DateFormatter() let sunMoonDateFormatter = DateFormatter()
sunMoonDateFormatter.timeZone = TimeZone(identifier: "UTC") sunMoonDateFormatter.timeZone = TimeZone(identifier: "UTC")
sunMoonDateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" sunMoonDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let sunriseUtc = sunriseUtc { if let sunriseUtc = sunriseUtc {
result.sunrise = sunMoonDateFormatter.date(from: sunriseUtc) result.sunrise = sunMoonDateFormatter.date(from: sunriseUtc)
} }
......
...@@ -39,7 +39,7 @@ struct WdtHourlySummary: Codable { ...@@ -39,7 +39,7 @@ struct WdtHourlySummary: Codable {
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> HourlyWeather? { public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> HourlyWeather? {
let log = WdtHourlySummary.log let log = WdtHourlySummary.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: dateTimeLocal) else { guard let date = dateFormatter.date(from: dateTimeLocal) else {
......
...@@ -45,7 +45,7 @@ struct WdtSurfaceObservation: Codable { ...@@ -45,7 +45,7 @@ struct WdtSurfaceObservation: Codable {
public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> CurrentWeather? { public func toAppModel(timeZone: TimeZone, updatedAt: Date) -> CurrentWeather? {
let log = WdtSurfaceObservation.log let log = WdtSurfaceObservation.log
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = timeZone dateFormatter.timeZone = timeZone
guard let date = dateFormatter.date(from: self.dateTimeLocal) else { guard let date = dateFormatter.date(from: self.dateTimeLocal) else {
...@@ -88,7 +88,7 @@ struct WdtSurfaceObservation: Codable { ...@@ -88,7 +88,7 @@ struct WdtSurfaceObservation: Codable {
let sunDateFormatter = DateFormatter() let sunDateFormatter = DateFormatter()
sunDateFormatter.timeZone = timeZone sunDateFormatter.timeZone = timeZone
sunDateFormatter.dateFormat = "YYYY-MM-dd hh:mm a" sunDateFormatter.dateFormat = "yyyy-MM-dd hh:mm a"
result.sunrise = sunDateFormatter.date(from: sunriseLocalDateTime) result.sunrise = sunDateFormatter.date(from: sunriseLocalDateTime)
result.sunset = sunDateFormatter.date(from: sunsetLocalDateTime) result.sunset = sunDateFormatter.date(from: sunsetLocalDateTime)
} }
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
//Forecast //Forecast
"forecast.sunny" = "Sunny"; "forecast.sunny" = "Sunny";
"forecast.clear" = "Clear";
"forecast.cloudy" = "Cloudy"; "forecast.cloudy" = "Cloudy";
"forecast.partlyCloudyDay" = "Partly Cloudy"; "forecast.partlyCloudyDay" = "Partly Cloudy";
"forecast.snowyDay" = "Snowy Day"; "forecast.snowyDay" = "Snowy Day";
"forecast.snowyNight" = "Snowy Night"; "forecast.snowyNight" = "Snowy Night";
"forecast.clearDay" = "Clear Day";
"forecast.clearNight" = "Clear Night"; "forecast.clearNight" = "Clear Night";
"forecast.partlyCloudyNight" = "Partly Cloudy Night"; "forecast.partlyCloudyNight" = "Partly Cloudy Night";
"forecast.thunderstorm" = "Thunderstorm"; "forecast.thunderstorm" = "Thunderstorm";
......
...@@ -6,8 +6,11 @@ ...@@ -6,8 +6,11 @@
// //
import UIKit import UIKit
import SnapKit
class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol { class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol {
private let kGraphInset:CGFloat = 10
private let kPrecipImageWidth:CGFloat = 20
private let dateLabel = UILabel() private let dateLabel = UILabel()
private let weatherImageView = UIImageView() private let weatherImageView = UIImageView()
private let weatherTypeLabel = UILabel() private let weatherTypeLabel = UILabel()
...@@ -15,23 +18,91 @@ class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -15,23 +18,91 @@ class ForecastDetailPeriodButton: UIControl, PeriodButtonProtocol {
private let minTempLabel = UILabel() private let minTempLabel = UILabel()
private let precipLabel = UILabel() private let precipLabel = UILabel()
private let precipImageView = UIImageView() private let precipImageView = UIImageView()
private var precipImageWidth:Constraint?
private static var formatter: DateFormatter = {
let fmt = DateFormatter()
fmt.dateFormat = "d, E"
return fmt
}()
//Public
public var tinted: Bool {
return false
}
public var index = -1 public var index = -1
var graphRect:CGRect {
let topInset = self.maxTempLabel.frame.origin.y + self.maxTempLabel.frame.size.height + kGraphInset
return .init(x: 0,
y: topInset,
width: self.bounds.width,
height: self.minTempLabel.frame.origin.y - topInset - kGraphInset)
}
required init() { required init() {
super.init(frame: .zero) super.init(frame: .zero)
prepareButton()
prepareDateLabel()
prepareWeatherInfo()
preparePreicpitaitonView()
prepareTempLabels()
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override var isSelected: Bool {
didSet {
if isSelected {
self.backgroundColor = UIColor(hex: 0x1f67f3)
self.dateLabel.font = AppFont.SFPro.bold(size: 16)
self.dateLabel.textColor = .white
self.weatherTypeLabel.textColor = .white
self.maxTempLabel.font = AppFont.SFPro.bold(size: 16)
self.maxTempLabel.textColor = .white
self.minTempLabel.textColor = .white
self.precipLabel.textColor = .white
self.precipImageView.tintColor = .white
}
else {
self.backgroundColor = UIColor(hex: 0xeceef6)
self.dateLabel.font = AppFont.SFPro.regular(size: 16)
self.dateLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
self.weatherTypeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
self.maxTempLabel.font = AppFont.SFPro.regular(size: 16)
self.maxTempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
self.minTempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
self.precipLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
self.precipImageView.tintColor = UIColor(hex: 0x1f67f3)
}
}
}
func configure(dailyWeather: DailyWeather) { func configure(dailyWeather: DailyWeather) {
// if Calendar.current.isDateInToday(dailyWeather.date) {
dateLabel.text = "day.today".localized()
}
else {
dateLabel.text = ForecastDetailPeriodButton.formatter.string(from: dailyWeather.date)
}
weatherImageView.image = dailyWeather.type.image(isDay: true)
weatherTypeLabel.text = dailyWeather.type.localized(isDay: true)
maxTempLabel.text = dailyWeather.maxTemp?.shortString
minTempLabel.text = dailyWeather.minTemp?.shortString
let percent = dailyWeather.precipitationProbability ?? 0
precipLabel.text = "\(percent)%"
precipImageView.isHidden = percent == 0
precipImageWidth?.layoutConstraints.first?.constant = percent == 0 ? 0 : kPrecipImageWidth
} }
func configure(hourlyWeather: HourlyWeather) { func configure(hourlyWeather: HourlyWeather) {
// assertionFailure("Not implemented for this weather type")
} }
} }
...@@ -45,6 +116,96 @@ private extension ForecastDetailPeriodButton { ...@@ -45,6 +116,96 @@ private extension ForecastDetailPeriodButton {
} }
func prepareDateLabel() { func prepareDateLabel() {
dateLabel.isUserInteractionEnabled = false
dateLabel.textColor = ThemeManager.currentTheme.secondaryTextColor dateLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
dateLabel.font = AppFont.SFPro.regular(size: 14)
addSubview(dateLabel)
dateLabel.snp.makeConstraints { (make) in
make.top.equalToSuperview().inset(16)
make.centerX.equalToSuperview()
}
}
func prepareWeatherInfo() {
weatherImageView.isUserInteractionEnabled = false
weatherImageView.contentMode = .scaleAspectFit
addSubview(weatherImageView)
weatherImageView.snp.makeConstraints { (make) in
make.width.height.equalTo(28)
make.top.equalTo(dateLabel.snp.bottom).offset(8)
make.centerX.equalToSuperview()
make.left.right.equalToSuperview().inset(20)
}
weatherTypeLabel.isUserInteractionEnabled = false
weatherTypeLabel.textAlignment = .center
weatherTypeLabel.numberOfLines = 2
weatherTypeLabel.lineBreakMode = .byWordWrapping
weatherTypeLabel.font = AppFont.SFPro.regular(size: 12)
weatherTypeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
addSubview(weatherTypeLabel)
weatherTypeLabel.snp.makeConstraints { (make) in
make.top.equalTo(weatherImageView.snp.bottom).offset(2)
make.centerX.equalToSuperview()
make.left.right.equalToSuperview().inset(4)
}
}
func prepareTempLabels() {
maxTempLabel.isUserInteractionEnabled = false
maxTempLabel.font = AppFont.SFPro.regular(size: 16)
maxTempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
addSubview(maxTempLabel)
maxTempLabel.snp.makeConstraints { (make) in
make.top.equalTo(weatherImageView.snp.bottom).offset(34)
make.centerX.equalToSuperview()
}
minTempLabel.isUserInteractionEnabled = false
minTempLabel.font = AppFont.SFPro.regular(size: 12)
minTempLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
addSubview(minTempLabel)
minTempLabel.snp.makeConstraints { (make) in
make.bottom.equalTo(precipImageView.snp.top).offset(-28)
make.centerX.equalToSuperview()
}
}
func preparePreicpitaitonView() {
let container = UIView()
precipImageView.isUserInteractionEnabled = false
precipImageView.image = UIImage(named: "humidity")?.withRenderingMode(.alwaysTemplate)
precipImageView.tintColor = UIColor(hex: 0x1f67f3)
precipImageView.contentMode = .scaleAspectFit
container.addSubview(precipImageView)
precipImageView.snp.makeConstraints { (make) in
self.precipImageWidth = make.width.equalTo(kPrecipImageWidth).constraint
make.height.equalTo(12)
make.top.left.bottom.equalToSuperview()
}
precipLabel.isUserInteractionEnabled = false
precipLabel.textAlignment = .left
precipLabel.font = AppFont.SFPro.regular(size: 12)
precipLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
container.addSubview(precipLabel)
precipLabel.snp.makeConstraints { (make) in
make.left.equalTo(precipImageView.snp.right).inset(2)
make.right.equalToSuperview()
}
addSubview(container)
container.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().inset(20)
}
} }
} }
...@@ -9,12 +9,12 @@ import UIKit ...@@ -9,12 +9,12 @@ import UIKit
class ForecastPeriodButton: UIControl, PeriodButtonProtocol { class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
//Private //Private
private let hourlyFormatter: DateFormatter = { private static var hourlyFormatter: DateFormatter = {
let fmt = DateFormatter() let fmt = DateFormatter()
fmt.dateFormat = "h a" fmt.dateFormat = "h a"
return fmt return fmt
}() }()
private let dailyFormatter: DateFormatter = { private static var dailyFormatter: DateFormatter = {
let fmt = DateFormatter() let fmt = DateFormatter()
fmt.dateFormat = "d, E" fmt.dateFormat = "d, E"
return fmt return fmt
...@@ -28,6 +28,9 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -28,6 +28,9 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
//Public //Public
public var tinted: Bool {
return true
}
public var index = -1 public var index = -1
var graphRect:CGRect { var graphRect:CGRect {
let topInset = self.tempLabel.frame.origin.y + self.tempLabel.frame.size.height + kGraphInset let topInset = self.tempLabel.frame.origin.y + self.tempLabel.frame.size.height + kGraphInset
...@@ -90,7 +93,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -90,7 +93,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
self.timeLabel.text = "day.today".localized() self.timeLabel.text = "day.today".localized()
} }
else { else {
self.timeLabel.text = dailyFormatter.string(from: dailyWeather.date) ForecastPeriodButton.dailyFormatter.timeZone = dailyWeather.timeZone
self.timeLabel.text = ForecastPeriodButton.dailyFormatter.string(from: dailyWeather.date)
} }
} }
...@@ -98,7 +102,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol { ...@@ -98,7 +102,8 @@ class ForecastPeriodButton: UIControl, PeriodButtonProtocol {
self.tempLabel.text = hourlyWeather.temp?.shortString self.tempLabel.text = hourlyWeather.temp?.shortString
self.minTempLabel.text = nil self.minTempLabel.text = nil
self.indicatorImageView.image = nil self.indicatorImageView.image = nil
self.timeLabel.text = hourlyFormatter.string(from: hourlyWeather.date) ForecastPeriodButton.hourlyFormatter.timeZone = hourlyWeather.timeZone
self.timeLabel.text = ForecastPeriodButton.hourlyFormatter.string(from: hourlyWeather.date)
} }
} }
......
...@@ -25,7 +25,8 @@ class ForecastTimePeriodView: UIView { ...@@ -25,7 +25,8 @@ class ForecastTimePeriodView: UIView {
private var currentTimePeriod = TimePeriod.daily private var currentTimePeriod = TimePeriod.daily
private var dailyGraphPoints = DailyGraphPoints(maxTempPoints: [CGPoint](), minTempPoints: [CGPoint]()) private var dailyGraphPoints = DailyGraphPoints(maxTempPoints: [CGPoint](), minTempPoints: [CGPoint]())
private var hourlyGraphPoints = HourlyGraphPoints(points: [CGPoint]()) private var hourlyGraphPoints = HourlyGraphPoints(points: [CGPoint]())
private var forecastTimePeriod:ForecastTimePeriod = ForecastTimePeriod(daily: [DailyWeather](), hourly: [HourlyWeather]()) private var daily = [DailyWeather]()
private var hourly = [HourlyWeather]()
//MARK:- View life cycle //MARK:- View life cycle
init() { init() {
...@@ -42,8 +43,9 @@ class ForecastTimePeriodView: UIView { ...@@ -42,8 +43,9 @@ class ForecastTimePeriodView: UIView {
} }
//Public //Public
public func set(forecastTimePeriod: ForecastTimePeriod) { public func set(location: Location) {
self.forecastTimePeriod = forecastTimePeriod self.daily = location.daily
self.hourly = location.hourly
} }
public func set(timePeriod:TimePeriod, buttonType: PeriodButtonProtocol.Type) { public func set(timePeriod:TimePeriod, buttonType: PeriodButtonProtocol.Type) {
...@@ -61,18 +63,18 @@ class ForecastTimePeriodView: UIView { ...@@ -61,18 +63,18 @@ class ForecastTimePeriodView: UIView {
let numberOfButtons:Int let numberOfButtons:Int
switch currentTimePeriod { switch currentTimePeriod {
case .daily: case .daily:
numberOfButtons = forecastTimePeriod.daily.count numberOfButtons = daily.count
case .hourly: case .hourly:
numberOfButtons = forecastTimePeriod.hourly.count numberOfButtons = hourly.count
} }
for index in 0..<numberOfButtons { for index in 0..<numberOfButtons {
let forecastButton = buttonType.init() let forecastButton = buttonType.init()
switch currentTimePeriod { switch currentTimePeriod {
case .daily: case .daily:
forecastButton.configure(dailyWeather: forecastTimePeriod.daily[index]) forecastButton.configure(dailyWeather: daily[index])
case .hourly: case .hourly:
forecastButton.configure(hourlyWeather: forecastTimePeriod.hourly[index]) forecastButton.configure(hourlyWeather: hourly[index])
} }
forecastButton.index = index forecastButton.index = index
forecastButton.addTarget(self, action: #selector(handleForecastButton(button:)), for: .touchUpInside) forecastButton.addTarget(self, action: #selector(handleForecastButton(button:)), for: .touchUpInside)
...@@ -90,7 +92,7 @@ class ForecastTimePeriodView: UIView { ...@@ -90,7 +92,7 @@ class ForecastTimePeriodView: UIView {
private func updateGraphLayout() { private func updateGraphLayout() {
print("[ForecastTimePeriod] Update graph layout") print("[ForecastTimePeriod] Update graph layout")
graphRect = (stackView.arrangedSubviews.first as? ForecastPeriodButton)?.graphRect ?? .zero graphRect = (stackView.arrangedSubviews.first as? PeriodButtonProtocol)?.graphRect ?? .zero
graphView.frame = .init(x: 0, graphView.frame = .init(x: 0,
y: graphRect.origin.y, y: graphRect.origin.y,
width: stackView.frame.width, width: stackView.frame.width,
...@@ -110,16 +112,16 @@ class ForecastTimePeriodView: UIView { ...@@ -110,16 +112,16 @@ class ForecastTimePeriodView: UIView {
} }
private func updateDailyGraphPoints() { private func updateDailyGraphPoints() {
let daysCount = forecastTimePeriod.daily.count let daysCount = daily.count
let maxTemps = (forecastTimePeriod.daily.map{ CGFloat($0.maxTemp?.localeValue ?? 0) }) let maxTemps = (daily.map{ CGFloat($0.maxTemp?.localeValue ?? 0) })
let topMaxTemp = maxTemps.max() ?? 0 let topMaxTemp = maxTemps.max() ?? 0
let minTemps = (forecastTimePeriod.daily.map{ CGFloat($0.minTemp?.localeValue ?? 0) }) let minTemps = (daily.map{ CGFloat($0.minTemp?.localeValue ?? 0) })
let topMinTemp = minTemps.max() ?? 0 let topMinTemp = minTemps.max() ?? 0
var maxPoints = [CGPoint]() var maxPoints = [CGPoint]()
var minPoints = [CGPoint]() var minPoints = [CGPoint]()
for index in 0..<daysCount { for index in 0..<daysCount {
guard let stackButton = stackView.arrangedSubviews[index] as? ForecastPeriodButton else { continue } guard let stackButton = stackView.arrangedSubviews[index] as? PeriodButtonProtocol else { continue }
let buttonRightSide = stackButton.frame.origin.x + stackButton.bounds.width let buttonRightSide = stackButton.frame.origin.x + stackButton.bounds.width
let buttonCenterX = (buttonRightSide + stackButton.frame.origin.x) / 2 let buttonCenterX = (buttonRightSide + stackButton.frame.origin.x) / 2
...@@ -148,14 +150,14 @@ class ForecastTimePeriodView: UIView { ...@@ -148,14 +150,14 @@ class ForecastTimePeriodView: UIView {
} }
private func updateHourlyGraphPoints() { private func updateHourlyGraphPoints() {
let hoursCount = forecastTimePeriod.hourly.count let hoursCount = hourly.count
let temps = (forecastTimePeriod.hourly.map{ CGFloat($0.temp?.localeValue ?? 0) }) let temps = (hourly.map{ CGFloat($0.temp?.localeValue ?? 0) })
let maxTemp = temps.max() ?? 0 let maxTemp = temps.max() ?? 0
var points = [CGPoint]() var points = [CGPoint]()
for index in 0..<hoursCount { for index in 0..<hoursCount {
guard let stackButton = stackView.arrangedSubviews[index] as? ForecastPeriodButton else { continue } guard let stackButton = stackView.arrangedSubviews[index] as? PeriodButtonProtocol else { continue }
let buttonRightSide = stackButton.frame.origin.x + stackButton.bounds.width let buttonRightSide = stackButton.frame.origin.x + stackButton.bounds.width
let buttonCenterX = (buttonRightSide + stackButton.frame.origin.x) / 2 let buttonCenterX = (buttonRightSide + stackButton.frame.origin.x) / 2
...@@ -176,7 +178,7 @@ class ForecastTimePeriodView: UIView { ...@@ -176,7 +178,7 @@ class ForecastTimePeriodView: UIView {
private func drawGraph() { private func drawGraph() {
guard guard
let periodButtons = stackView.arrangedSubviews as? [ForecastPeriodButton], let periodButtons = stackView.arrangedSubviews as? [PeriodButtonProtocol],
let selectedButton = (periodButtons.first{ $0.isSelected }) let selectedButton = (periodButtons.first{ $0.isSelected })
else { else {
return return
...@@ -196,7 +198,9 @@ class ForecastTimePeriodView: UIView { ...@@ -196,7 +198,9 @@ class ForecastTimePeriodView: UIView {
print("[ForecastTimePeriod] Draw graph") print("[ForecastTimePeriod] Draw graph")
} }
private func tintGraphAt(button:ForecastPeriodButton) { private func tintGraphAt(button:PeriodButtonProtocol) {
guard button.tinted else { return }
switch currentTimePeriod { switch currentTimePeriod {
case .daily: case .daily:
self.graphView.tintGraphFrom(startPointX: button.frame.origin.x, self.graphView.tintGraphFrom(startPointX: button.frame.origin.x,
...@@ -210,9 +214,9 @@ class ForecastTimePeriodView: UIView { ...@@ -210,9 +214,9 @@ class ForecastTimePeriodView: UIView {
} }
} }
@objc private func handleForecastButton(button:ForecastPeriodButton) { @objc private func handleForecastButton(button:UIControl) {
stackView.arrangedSubviews.forEach { stackView.arrangedSubviews.forEach {
if let periodButton = $0 as? ForecastPeriodButton { if let periodButton = $0 as? PeriodButtonProtocol {
periodButton.isSelected = periodButton === button periodButton.isSelected = periodButton === button
if periodButton.isSelected { if periodButton.isSelected {
......
...@@ -12,4 +12,6 @@ public protocol PeriodButtonProtocol: UIControl { ...@@ -12,4 +12,6 @@ public protocol PeriodButtonProtocol: UIControl {
func configure(dailyWeather: DailyWeather) func configure(dailyWeather: DailyWeather)
func configure(hourlyWeather: HourlyWeather) func configure(hourlyWeather: HourlyWeather)
var index: Int { get set } var index: Int { get set }
var graphRect:CGRect { get }
var tinted:Bool { get }
} }
...@@ -16,6 +16,7 @@ class ForecastTimePeriodCell: UITableViewCell { ...@@ -16,6 +16,7 @@ class ForecastTimePeriodCell: UITableViewCell {
private let gradientView = GradientView(startColor: UIColor(hex: 0xffffff).withAlphaComponent(0), private let gradientView = GradientView(startColor: UIColor(hex: 0xffffff).withAlphaComponent(0),
endColor: UIColor(hex: 0xdaddec), endColor: UIColor(hex: 0xdaddec),
opacity: 0.5) opacity: 0.5)
private var graphIsDrawn = false
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
...@@ -32,12 +33,25 @@ class ForecastTimePeriodCell: UITableViewCell { ...@@ -32,12 +33,25 @@ class ForecastTimePeriodCell: UITableViewCell {
//Public //Public
public func configure(with location:Location) { public func configure(with location:Location) {
let forecastTimePeriod = ForecastTimePeriod(daily: location.daily, hourly: location.hourly) self.forecastTimePeriodView.set(location: location)
self.forecastTimePeriodView.set(forecastTimePeriod: forecastTimePeriod)
if graphIsDrawn == false {
self.handleSegmentDidChange()
self.graphIsDrawn = true
}
} }
@objc private func handleSegmentDidChange() { @objc private func handleSegmentDidChange() {
guard let timePeriod = TimePeriod(rawValue: self.periodSegmentedControl.selectedSegmentIndex) else {
return
}
switch timePeriod {
case .daily:
self.forecastTimePeriodView.set(timePeriod: timePeriod, buttonType: ForecastDetailPeriodButton.self)
case .hourly:
self.forecastTimePeriodView.set(timePeriod: timePeriod, buttonType: ForecastPeriodButton.self)
}
} }
} }
......
...@@ -33,8 +33,7 @@ class CityForecastTimePeriodCell: UITableViewCell { ...@@ -33,8 +33,7 @@ class CityForecastTimePeriodCell: UITableViewCell {
//Public //Public
public func configure(with location:Location) { public func configure(with location:Location) {
let forecastTimePeriod = ForecastTimePeriod(daily: location.daily, hourly: location.hourly) self.forecastTimePeriodView.set(location: location)
self.forecastTimePeriodView.set(forecastTimePeriod: forecastTimePeriod)
if graphIsDrawn == false { if graphIsDrawn == false {
self.handleSegmentDidChange() self.handleSegmentDidChange()
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
<key>XMLCoder.xcscheme_^#shared#^_</key> <key>XMLCoder.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>5</integer> <integer>6</integer>
</dict> </dict>
</dict> </dict>
<key>SuppressBuildableAutocreation</key> <key>SuppressBuildableAutocreation</key>
......
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