Commit c73bf18b by Dmitry Stepanets

Working on levels

parent 67758c81
......@@ -30,17 +30,29 @@ private class MinutelyLevelView: UIView {
}
}
private extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
var seen: Set<Iterator.Element> = []
return filter { seen.insert($0).inserted }
}
}
class MinutelyForecastView: UIView {
//Private
private let kTemperatureColors = [UIColor(hex: 0xff934f), UIColor(hex: 0xff414a)]
private let kPrecipitationColors = [UIColor(hex: 0x2d99ff), UIColor(hex: 0x8fc6fb)]
private let detailsInfoView = UIView()
private let levelsStackView = UIStackView()
private let verticalStackView = UIStackView()
private let scrollView = UIScrollView()
private var location: Location?
init() {
super.init(frame: .zero)
prepareDetailView()
prepareVerticalStackView()
prepareScrollView()
}
override func layoutSubviews() {
......@@ -52,10 +64,38 @@ class MinutelyForecastView: UIView {
func configure(with location: Location) {
self.location = location
updateView()
}
private func updateView() {
verticalStackView.removeAll()
levelsStackView.removeAll()
prepareDetailView()
prepareVerticalStackView()
prepareScrollView()
guard
let forecast = location?.minutely?.forecast,
let maxTemp = (forecast.compactMap{$0.temp}.max{$0.value < $1.value})
else {
return
}
let uniqTemps = forecast.compactMap{$0.temp}.unique().sorted{$0.value > $1.value}
for temp in uniqTemps {
let label = UILabel()
label.text = temp.settingsConverted.shortString
label.font = AppFont.SFPro.regular(size: 10)
verticalStackView.addArrangedSubview(label)
}
for index in 0..<forecast.count {
let view = MinutelyLevelView()
levelsStackView.addArrangedSubview(view)
let level = uniqTemps.firstIndex {$0.value == forecast[index].temp.value} ?? 0
view.snp.makeConstraints { make in
make.width.equalTo(3)
make.height.equalToSuperview().multipliedBy(1/Double(max(1,level)))
}
}
}
required init?(coder: NSCoder) {
......@@ -77,21 +117,13 @@ private extension MinutelyForecastView {
}
func prepareVerticalStackView() {
verticalStackView.removeAll()
verticalStackView.axis = .vertical
verticalStackView.distribution = .fillProportionally
verticalStackView.alignment = .fill
verticalStackView.isBaselineRelativeArrangement = false
verticalStackView.isLayoutMarginsRelativeArrangement = false
for index in 0..<4 {
let label = UILabel()
label.text = "\(29 - index)°"
label.font = AppFont.SFPro.regular(size: 10)
verticalStackView.addArrangedSubview(label)
}
addSubview(verticalStackView)
verticalStackView.snp.makeConstraints { make in
make.left.equalToSuperview().inset(20)
make.top.equalTo(detailsInfoView.snp.bottom).offset(8)
......@@ -100,10 +132,9 @@ private extension MinutelyForecastView {
}
func prepareScrollView() {
scrollView.backgroundColor = .red
scrollView.backgroundColor = .lightGray
addSubview(scrollView)
let levelsStackView = UIStackView()
levelsStackView.axis = .horizontal
levelsStackView.spacing = 2
levelsStackView.distribution = .fill
......@@ -120,14 +151,5 @@ private extension MinutelyForecastView {
make.right.equalToSuperview().inset(20)
make.bottom.equalToSuperview().inset(40)
}
for _ in 0..<300 {
let view = MinutelyLevelView()
levelsStackView.addArrangedSubview(view)
view.snp.makeConstraints { make in
make.width.equalTo(3)
make.height.equalToSuperview().multipliedBy(Double.random(in: 0...0.9))
}
}
}
}
......@@ -28,7 +28,7 @@ public class BlendMinutelySource: MinutelyForecastSource {
private let kTempUnit = "F"
private lazy var dateFormatter: DateFormatter = {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd'T'hh:mm:ss.sss'Z'"
fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return fmt
}()
/// This queue is needed to synchronize access to locationsBeingUpdated. Also, to make logging more clear.
......@@ -124,7 +124,13 @@ public class BlendMinutelySource: MinutelyForecastSource {
completion(.success(forecast))
}
catch {
completion(.failure(BlendMinutelySourceError.dataEncodingError(error.localizedDescription)))
guard let bodyData = data else {
completion(.failure(BlendMinutelySourceError.dataEncodingError(error.localizedDescription)))
return
}
let body = String(data: bodyData, encoding: .utf8) ?? "N/A"
completion(.failure(BlendMinutelySourceError.dataEncodingError(body)))
}
}
.resume()
......
......@@ -31,6 +31,8 @@ public class LocationManager {
private let legacyMigrator = LegacyMigrationManager()
private var defaultLocation = Location(deviceLocation: false,
coordinates: .init(latitude: 37.3230, longitude: -122.0322), // Cupertino
region: "US",
cityName: "Cupertino",
timeZone: TimeZone(abbreviation: "PST")!) {
didSet {
if locations.count == 0 {
......
......@@ -8,11 +8,11 @@
import Foundation
public struct MinutelyItem {
let time: Date
let temp: Temperature
let precipitation: Double
let windSpeed: WindSpeed
let pressure: Pressure
public let time: Date
public let temp: Temperature
public let precipitation: Double
public let windSpeed: WindSpeed
public let pressure: Pressure
public init(time: Date, temp: Temperature, precipitation: Double, windSpeed: WindSpeed, pressure: Pressure) {
self.time = time
......
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