Commit 6da24400 by Dmitry Stepanets

Working on minutely foreacst detail view

parent 98174d0b
...@@ -195,6 +195,7 @@ ...@@ -195,6 +195,7 @@
CDD75F0D25DE68B10099ACDB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CDD75F0F25DE68B10099ACDB /* Localizable.strings */; }; CDD75F0D25DE68B10099ACDB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CDD75F0F25DE68B10099ACDB /* Localizable.strings */; };
CDDCD50726809F6D00E089AD /* ShortsSwipeHelperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDCD50626809F6D00E089AD /* ShortsSwipeHelperView.swift */; }; CDDCD50726809F6D00E089AD /* ShortsSwipeHelperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDCD50626809F6D00E089AD /* ShortsSwipeHelperView.swift */; };
CDDCD5092680C18B00E089AD /* ShortsUnreadNudgeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDCD5082680C18B00E089AD /* ShortsUnreadNudgeView.swift */; }; CDDCD5092680C18B00E089AD /* ShortsUnreadNudgeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDCD5082680C18B00E089AD /* ShortsUnreadNudgeView.swift */; };
CDDE2E9526D8DCAF00B32C05 /* MinutelyForecastDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDE2E9426D8DCAF00B32C05 /* MinutelyForecastDetailsView.swift */; };
CDDE8D7C262EED3C00267931 /* MapLegendSevereView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDE8D7B262EED3C00267931 /* MapLegendSevereView.swift */; }; CDDE8D7C262EED3C00267931 /* MapLegendSevereView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDE8D7B262EED3C00267931 /* MapLegendSevereView.swift */; };
CDDE8D7F262EED4D00267931 /* MapLegendWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDE8D7E262EED4D00267931 /* MapLegendWeatherView.swift */; }; CDDE8D7F262EED4D00267931 /* MapLegendWeatherView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDE8D7E262EED4D00267931 /* MapLegendWeatherView.swift */; };
CDE18DCD25D1666700C80ED9 /* ForecastCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */; }; CDE18DCD25D1666700C80ED9 /* ForecastCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */; };
...@@ -500,6 +501,7 @@ ...@@ -500,6 +501,7 @@
CDD75F0E25DE68B10099ACDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; }; CDD75F0E25DE68B10099ACDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
CDDCD50626809F6D00E089AD /* ShortsSwipeHelperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsSwipeHelperView.swift; sourceTree = "<group>"; }; CDDCD50626809F6D00E089AD /* ShortsSwipeHelperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsSwipeHelperView.swift; sourceTree = "<group>"; };
CDDCD5082680C18B00E089AD /* ShortsUnreadNudgeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsUnreadNudgeView.swift; sourceTree = "<group>"; }; CDDCD5082680C18B00E089AD /* ShortsUnreadNudgeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsUnreadNudgeView.swift; sourceTree = "<group>"; };
CDDE2E9426D8DCAF00B32C05 /* MinutelyForecastDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinutelyForecastDetailsView.swift; sourceTree = "<group>"; };
CDDE8D7B262EED3C00267931 /* MapLegendSevereView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLegendSevereView.swift; sourceTree = "<group>"; }; CDDE8D7B262EED3C00267931 /* MapLegendSevereView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLegendSevereView.swift; sourceTree = "<group>"; };
CDDE8D7E262EED4D00267931 /* MapLegendWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLegendWeatherView.swift; sourceTree = "<group>"; }; CDDE8D7E262EED4D00267931 /* MapLegendWeatherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLegendWeatherView.swift; sourceTree = "<group>"; };
CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastCoordinator.swift; sourceTree = "<group>"; }; CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastCoordinator.swift; sourceTree = "<group>"; };
...@@ -1186,11 +1188,11 @@ ...@@ -1186,11 +1188,11 @@
CDADBBA526D654FA006E4565 /* SharedViews */ = { CDADBBA526D654FA006E4565 /* SharedViews */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDDE2E9326D8DC8900B32C05 /* MinutelyForecastView */,
CD0A2CC325FA5857006148A4 /* ForecastTimePeriod */, CD0A2CC325FA5857006148A4 /* ForecastTimePeriod */,
CD1237F3255D889F00C98139 /* GradientView.swift */, CD1237F3255D889F00C98139 /* GradientView.swift */,
CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */, CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */,
CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */, CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */,
CDADBBA626D6552A006E4565 /* MinutelyForecastView.swift */,
); );
path = SharedViews; path = SharedViews;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1301,6 +1303,15 @@ ...@@ -1301,6 +1303,15 @@
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CDDE2E9326D8DC8900B32C05 /* MinutelyForecastView */ = {
isa = PBXGroup;
children = (
CDADBBA626D6552A006E4565 /* MinutelyForecastView.swift */,
CDDE2E9426D8DCAF00B32C05 /* MinutelyForecastDetailsView.swift */,
);
path = MinutelyForecastView;
sourceTree = "<group>";
};
CDE18DCF25D166DD00C80ED9 /* Forecast */ = { CDE18DCF25D166DD00C80ED9 /* Forecast */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -1955,6 +1966,7 @@ ...@@ -1955,6 +1966,7 @@
CD593BCF2608A50900C93428 /* ForecastHourlyCell.swift in Sources */, CD593BCF2608A50900C93428 /* ForecastHourlyCell.swift in Sources */,
CDB0D4CC2670D12F0081C773 /* TodayShortsCell.swift in Sources */, CDB0D4CC2670D12F0081C773 /* TodayShortsCell.swift in Sources */,
CD1DDD332602305200AC62B2 /* ForecastInfoCell.swift in Sources */, CD1DDD332602305200AC62B2 /* ForecastInfoCell.swift in Sources */,
CDDE2E9526D8DCAF00B32C05 /* MinutelyForecastDetailsView.swift in Sources */,
CD8579792672214700CC4CDA /* UITableView+HeaderSize.swift in Sources */, CD8579792672214700CC4CDA /* UITableView+HeaderSize.swift in Sources */,
CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */, CDEE8AD725DA882200C289DE /* ForecastPeriodButton.swift in Sources */,
CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */, CDE18DD125D166F900C80ED9 /* ForecastViewController.swift in Sources */,
......
//
// MinutelyForecastDetailsView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.08.2021.
//
import UIKit
import OneWeatherCore
class MinutelyForecastDetailsView: UIView {
//Private
private let gradient = CAGradientLayer()
private let tempLabel = UILabel()
private let timeLabel = UILabel()
private let forecastImage = UIImageView()
private let triangle = CAShapeLayer()
private let triangleView = UIView()
private let formatter: DateFormatter
init() {
self.formatter = DateFormatter()
self.formatter.dateFormat = "h:mm a"
super.init(frame: .zero)
prepareTriangle()
prepareView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
//Gradient
gradient.frame = self.bounds
//Triangle
let bezierPath = UIBezierPath()
bezierPath.addLine(to: .init(x: triangleView.frame.width, y: 0))
bezierPath.addLine(to: .init(x: (triangleView.frame.width / 2).rounded(.down),
y: triangleView.frame.height))
bezierPath.addLine(to: .zero)
triangle.path = bezierPath.cgPath
}
func configure(hourly: HourlyWeather, colors: [UIColor]) {
gradient.colors = colors.map{ $0.cgColor }
triangle.fillColor = colors.last?.cgColor
timeLabel.text = formatter.string(from: hourly.date)
tempLabel.text = hourly.temp?.settingsConverted.shortString
forecastImage.image = hourly.type.image(isDay: hourly.isDay)
}
}
private extension MinutelyForecastDetailsView {
func prepareView() {
gradient.startPoint = .init(x: 0.5, y: 0)
gradient.endPoint = .init(x: 0.5, y: 1)
gradient.cornerRadius = 8
layer.addSublayer(gradient)
timeLabel.font = AppFont.SFPro.light(size: 12)
timeLabel.textColor = .white
addSubview(timeLabel)
tempLabel.font = AppFont.SFPro.bold(size: 24)
tempLabel.textColor = .white
addSubview(tempLabel)
forecastImage.contentMode = .scaleAspectFit
forecastImage.clipsToBounds = true
addSubview(forecastImage)
let separator = UIView()
separator.backgroundColor = .white.withAlphaComponent(0.5)
addSubview(separator)
//Constraints
self.snp.makeConstraints { make in
make.height.equalTo(38)
}
timeLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalToSuperview().inset(12)
}
separator.snp.makeConstraints { make in
make.width.equalTo(1)
make.height.equalToSuperview().multipliedBy(0.65)
make.left.equalTo(timeLabel.snp.right).offset(8)
make.centerY.equalToSuperview()
}
tempLabel.snp.makeConstraints { make in
make.left.equalTo(separator.snp.right).offset(8)
make.centerY.equalToSuperview()
}
forecastImage.snp.makeConstraints { make in
make.width.height.equalTo(28)
make.centerY.equalToSuperview()
make.left.equalTo(tempLabel.snp.right).offset(4)
make.right.equalToSuperview().inset(12)
}
}
func prepareTriangle() {
triangleView.layer.addSublayer(triangle)
addSubview(triangleView)
triangleView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview()
make.width.equalTo(12)
make.height.equalTo(10)
}
}
}
...@@ -57,10 +57,15 @@ private extension Sequence where Iterator.Element: Hashable { ...@@ -57,10 +57,15 @@ private extension Sequence where Iterator.Element: Hashable {
class MinutelyForecastView: UIView { class MinutelyForecastView: UIView {
//Private //Private
private let detailsInfoView = UIView() private let detailsInfoView = MinutelyForecastDetailsView()
private let levelsStackView = UIStackView() private let levelsStackView = UIStackView()
private let verticalStackView = UIStackView() private let verticalStackView = UIStackView()
private let scrollView = UIScrollView() private let scrollView = UIScrollView()
private lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
return formatter
}()
private var location: Location? private var location: Location?
init() { init() {
...@@ -80,10 +85,12 @@ class MinutelyForecastView: UIView { ...@@ -80,10 +85,12 @@ class MinutelyForecastView: UIView {
func configure(with location: Location) { func configure(with location: Location) {
self.location = location self.location = location
updateView() self.detailsInfoView.configure(hourly: location.hourly[0],
colors: kTemperatureColors)
updateChart()
} }
private func updateView() { private func updateChart() {
verticalStackView.removeAll() verticalStackView.removeAll()
levelsStackView.removeAll() levelsStackView.removeAll()
scrollView.subviews.forEach { scrollView.subviews.forEach {
...@@ -124,9 +131,6 @@ class MinutelyForecastView: UIView { ...@@ -124,9 +131,6 @@ class MinutelyForecastView: UIView {
verticalStackView.addArrangedSubview(label) verticalStackView.addArrangedSubview(label)
} }
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
for index in 0..<forecast.count { for index in 0..<forecast.count {
let view = MinutelyLevelView(forecastType: .temperature) let view = MinutelyLevelView(forecastType: .temperature)
levelsStackView.addArrangedSubview(view) levelsStackView.addArrangedSubview(view)
...@@ -140,7 +144,7 @@ class MinutelyForecastView: UIView { ...@@ -140,7 +144,7 @@ class MinutelyForecastView: UIView {
if minutes % 20 == 0 { if minutes % 20 == 0 {
let label = UILabel() let label = UILabel()
label.font = AppFont.SFPro.bold(size: 12) label.font = AppFont.SFPro.bold(size: 12)
label.text = formatter.string(from: forecast[index].time) label.text = dateFormatter.string(from: forecast[index].time)
scrollView.addSubview(label) scrollView.addSubview(label)
label.snp.makeConstraints { make in label.snp.makeConstraints { make in
...@@ -159,13 +163,12 @@ class MinutelyForecastView: UIView { ...@@ -159,13 +163,12 @@ class MinutelyForecastView: UIView {
//MARK:- Prepare //MARK:- Prepare
private extension MinutelyForecastView { private extension MinutelyForecastView {
func prepareDetailView() { func prepareDetailView() {
detailsInfoView.backgroundColor = kTemperatureColors[0]
addSubview(detailsInfoView) addSubview(detailsInfoView)
//Constraints
detailsInfoView.snp.makeConstraints { make in detailsInfoView.snp.makeConstraints { make in
make.top.equalToSuperview() make.top.equalToSuperview()
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
make.height.equalTo(38)
make.width.equalTo(200)
} }
} }
......
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