Commit 6644c623 by Dmitry Stepanets

Working on minutely forecast UI

parent c73bf18b
......@@ -7,17 +7,33 @@
import UIKit
import OneWeatherCore
import Accelerate
enum MinutelyForecastType {
case temperature
case precipitation
}
private let kTemperatureColors = [UIColor(hex: 0xff934f), UIColor(hex: 0xff414a)]
private let kPrecipitationColors = [UIColor(hex: 0x2d99ff), UIColor(hex: 0x8fc6fb)]
private class MinutelyLevelView: UIView {
init() {
private let gradient = CAGradientLayer()
init(forecastType: MinutelyForecastType) {
super.init(frame: .zero)
backgroundColor = .blue
gradient.startPoint = .init(x: 0.5, y: 0)
gradient.endPoint = .init(x: 0.5, y: 1)
switch forecastType {
case .temperature:
gradient.colors = kTemperatureColors.compactMap{ $0.cgColor }
case .precipitation:
gradient.colors = kPrecipitationColors.compactMap{ $0.cgColor }
}
layer.addSublayer(gradient)
}
required init?(coder: NSCoder) {
......@@ -26,7 +42,9 @@ private class MinutelyLevelView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.width / 2
gradient.cornerRadius = bounds.width / 2
gradient.frame = bounds
}
}
......@@ -39,8 +57,6 @@ private extension Sequence where Iterator.Element: Hashable {
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()
......@@ -51,14 +67,14 @@ class MinutelyForecastView: UIView {
super.init(frame: .zero)
prepareDetailView()
prepareVerticalStackView()
prepareScrollView()
prepareVerticalStackView()
}
override func layoutSubviews() {
super.layoutSubviews()
let leftInset = detailsInfoView.frame.origin.x
scrollView.contentInset = .init(top: 0, left: leftInset, bottom: 0, right: 0)
let leftInset = detailsInfoView.frame.origin.x - scrollView.frame.origin.x + detailsInfoView.frame.width / 2
scrollView.contentInset = .init(top: 0, left: leftInset, bottom: 0, right: leftInset + 20)
scrollView.setContentOffset(.init(x: -leftInset, y: 0), animated: false)
}
......@@ -70,15 +86,48 @@ class MinutelyForecastView: UIView {
private func updateView() {
verticalStackView.removeAll()
levelsStackView.removeAll()
scrollView.subviews.forEach {
if $0.isKind(of: UILabel.self) {
$0.removeFromSuperview()
}
}
guard
let forecast = location?.minutely?.forecast,
let maxTemp = (forecast.compactMap{$0.temp}.max{$0.value < $1.value})
let maxTemp = (forecast.compactMap{$0.temp}.max{$0.value < $1.value}),
let minTemp = (forecast.compactMap{$0.temp}.min{$0.value < $1.value})
else {
return
}
let uniqTemps = forecast.compactMap{$0.temp}.unique().sorted{$0.value > $1.value}
var uniqTemps = forecast.compactMap{$0.temp}.unique().sorted{$0.value > $1.value}
if uniqTemps.count > 4 {
var originalTimes = [Float]()
var originalValues = [Float]()
for time in 0..<uniqTemps.count {
originalTimes.append(Float(time))
originalValues.append(Float(uniqTemps[time].value))
}
var newValues = [Float](repeating: 0, count: 4)
let stride = vDSP_Stride(1)
vDSP_vlint(originalValues,
originalTimes, stride,
&newValues, stride,
4,
vDSP_Length(originalValues.count))
// vDSP_vgenpD(originalValues, stride,
// originalTimes, stride,
// &newValues, stride,
// vDSP_Length(newValues.count),
// vDSP_Length(originalValues.count))
let result = newValues.enumerated().map{ return $0 }
print("Break")
}
for temp in uniqTemps {
let label = UILabel()
......@@ -87,13 +136,29 @@ class MinutelyForecastView: UIView {
verticalStackView.addArrangedSubview(label)
}
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
for index in 0..<forecast.count {
let view = MinutelyLevelView()
let view = MinutelyLevelView(forecastType: .temperature)
levelsStackView.addArrangedSubview(view)
let level = uniqTemps.firstIndex {$0.value == forecast[index].temp.value} ?? 0
let level = (0.05 + 0.9 * ((forecast[index].temp.value - minTemp.value) / (maxTemp.value - minTemp.value)))
view.snp.makeConstraints { make in
make.width.equalTo(3)
make.height.equalToSuperview().multipliedBy(1/Double(max(1,level)))
make.height.equalToSuperview().multipliedBy(level)
}
let minutes = Calendar.current.component(.minute, from: forecast[index].time)
if minutes % 20 == 0 {
let label = UILabel()
label.font = AppFont.SFPro.bold(size: 12)
label.text = formatter.string(from: forecast[index].time)
scrollView.addSubview(label)
label.snp.makeConstraints { make in
make.top.equalTo(view.snp.bottom).offset(12)
make.centerX.equalTo(view)
}
}
}
}
......@@ -120,14 +185,12 @@ private extension MinutelyForecastView {
verticalStackView.axis = .vertical
verticalStackView.distribution = .fillProportionally
verticalStackView.alignment = .fill
verticalStackView.isBaselineRelativeArrangement = false
verticalStackView.isLayoutMarginsRelativeArrangement = false
addSubview(verticalStackView)
verticalStackView.snp.makeConstraints { make in
make.left.equalToSuperview().inset(20)
make.top.equalTo(detailsInfoView.snp.bottom).offset(8)
make.bottom.equalToSuperview().inset(40)
make.height.equalTo(levelsStackView)
make.right.equalTo(scrollView.snp.left).offset(-6)
make.top.equalTo(scrollView).inset(4)
}
}
......@@ -142,14 +205,16 @@ private extension MinutelyForecastView {
scrollView.addSubview(levelsStackView)
levelsStackView.snp.makeConstraints { (make) in
make.edges.height.equalToSuperview()
make.edges.equalToSuperview()
make.height.equalToSuperview().multipliedBy(0.8)
}
scrollView.snp.makeConstraints { make in
make.left.equalTo(verticalStackView.snp.right).offset(6)
make.left.equalToSuperview().inset(42)
make.top.equalTo(detailsInfoView.snp.bottom).offset(8)
make.right.equalToSuperview().inset(20)
make.bottom.equalToSuperview().inset(40)
make.height.equalTo(185)
}
}
}
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