Commit 67758c81 by Dmitriy Stepanets

Working on minutely forecast UI

parent aeccaa9b
...@@ -175,6 +175,8 @@ ...@@ -175,6 +175,8 @@
CDAC9B8526319B0500AC1BF4 /* MapTimeControlItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */; }; CDAC9B8526319B0500AC1BF4 /* MapTimeControlItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */; };
CDAD97B1262042B2007FCFB1 /* MapButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B0262042B2007FCFB1 /* MapButton.swift */; }; CDAD97B1262042B2007FCFB1 /* MapButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B0262042B2007FCFB1 /* MapButton.swift */; };
CDAD97B426207D14007FCFB1 /* MapTimeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */; }; CDAD97B426207D14007FCFB1 /* MapTimeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */; };
CDADBBA426D64948006E4565 /* MinutelyForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDADBBA326D64948006E4565 /* MinutelyForecastCell.swift */; };
CDADBBA726D6552A006E4565 /* MinutelyForecastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDADBBA626D6552A006E4565 /* MinutelyForecastView.swift */; };
CDB0D4CA2670CAD00081C773 /* ShortsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4C92670CAD00081C773 /* ShortsCollectionViewCell.swift */; }; CDB0D4CA2670CAD00081C773 /* ShortsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4C92670CAD00081C773 /* ShortsCollectionViewCell.swift */; };
CDB0D4CC2670D12F0081C773 /* TodayShortsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4CB2670D12F0081C773 /* TodayShortsCell.swift */; }; CDB0D4CC2670D12F0081C773 /* TodayShortsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4CB2670D12F0081C773 /* TodayShortsCell.swift */; };
CDB0D4CE2670DABF0081C773 /* UIImage+AverageColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4CD2670DABF0081C773 /* UIImage+AverageColor.swift */; }; CDB0D4CE2670DABF0081C773 /* UIImage+AverageColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB0D4CD2670DABF0081C773 /* UIImage+AverageColor.swift */; };
...@@ -478,6 +480,8 @@ ...@@ -478,6 +480,8 @@
CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlItem.swift; sourceTree = "<group>"; }; CDAC9B8426319B0500AC1BF4 /* MapTimeControlItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlItem.swift; sourceTree = "<group>"; };
CDAD97B0262042B2007FCFB1 /* MapButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButton.swift; sourceTree = "<group>"; }; CDAD97B0262042B2007FCFB1 /* MapButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButton.swift; sourceTree = "<group>"; };
CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlView.swift; sourceTree = "<group>"; }; CDAD97B326207D14007FCFB1 /* MapTimeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTimeControlView.swift; sourceTree = "<group>"; };
CDADBBA326D64948006E4565 /* MinutelyForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinutelyForecastCell.swift; sourceTree = "<group>"; };
CDADBBA626D6552A006E4565 /* MinutelyForecastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinutelyForecastView.swift; sourceTree = "<group>"; };
CDB0D4C92670CAD00081C773 /* ShortsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsCollectionViewCell.swift; sourceTree = "<group>"; }; CDB0D4C92670CAD00081C773 /* ShortsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortsCollectionViewCell.swift; sourceTree = "<group>"; };
CDB0D4CB2670D12F0081C773 /* TodayShortsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayShortsCell.swift; sourceTree = "<group>"; }; CDB0D4CB2670D12F0081C773 /* TodayShortsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayShortsCell.swift; sourceTree = "<group>"; };
CDB0D4CD2670DABF0081C773 /* UIImage+AverageColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+AverageColor.swift"; sourceTree = "<group>"; }; CDB0D4CD2670DABF0081C773 /* UIImage+AverageColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+AverageColor.swift"; sourceTree = "<group>"; };
...@@ -1171,9 +1175,30 @@ ...@@ -1171,9 +1175,30 @@
path = MapTimeControl; path = MapTimeControl;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CDADBBA226D64921006E4565 /* MinutelyForecastCell */ = {
isa = PBXGroup;
children = (
CDADBBA326D64948006E4565 /* MinutelyForecastCell.swift */,
);
path = MinutelyForecastCell;
sourceTree = "<group>";
};
CDADBBA526D654FA006E4565 /* SharedViews */ = {
isa = PBXGroup;
children = (
CD0A2CC325FA5857006148A4 /* ForecastTimePeriod */,
CD1237F3255D889F00C98139 /* GradientView.swift */,
CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */,
CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */,
CDADBBA626D6552A006E4565 /* MinutelyForecastView.swift */,
);
path = SharedViews;
sourceTree = "<group>";
};
CDC0C7AE261310DB0030607A /* SharedCells */ = { CDC0C7AE261310DB0030607A /* SharedCells */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDADBBA226D64921006E4565 /* MinutelyForecastCell */,
CEEB354A266F687300E16F90 /* AdCells */, CEEB354A266F687300E16F90 /* AdCells */,
CD86246325E66E6B0097F3FB /* PrecipCell */, CD86246325E66E6B0097F3FB /* PrecipCell */,
CD86245B25E646000097F3FB /* SunPhaseCell */, CD86245B25E646000097F3FB /* SunPhaseCell */,
...@@ -1221,6 +1246,7 @@ ...@@ -1221,6 +1246,7 @@
CDD0F1DC2572400200CF5017 /* UI */ = { CDD0F1DC2572400200CF5017 /* UI */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDADBBA526D654FA006E4565 /* SharedViews */,
CDC0C7AE261310DB0030607A /* SharedCells */, CDC0C7AE261310DB0030607A /* SharedCells */,
CD15DB3B25DA6C2800024727 /* Controls */, CD15DB3B25DA6C2800024727 /* Controls */,
CD6B3039257267FB004B34B3 /* Buttons */, CD6B3039257267FB004B34B3 /* Buttons */,
...@@ -1258,14 +1284,10 @@ ...@@ -1258,14 +1284,10 @@
CDD0F1F025725BD700CF5017 /* Helpers */ = { CDD0F1F025725BD700CF5017 /* Helpers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD0A2CC325FA5857006148A4 /* ForecastTimePeriod */,
CD6B304125726ABE004B34B3 /* Themes */, CD6B304125726ABE004B34B3 /* Themes */,
CD1237F3255D889F00C98139 /* GradientView.swift */,
CDD0F1E72572429E00CF5017 /* AppFont.swift */, CDD0F1E72572429E00CF5017 /* AppFont.swift */,
CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */, CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */,
CD50555E26983C14006776AB /* CubicCurveAlgorithm.swift */, CD50555E26983C14006776AB /* CubicCurveAlgorithm.swift */,
CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */,
CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */,
); );
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1885,6 +1907,7 @@ ...@@ -1885,6 +1907,7 @@
CEEB3549266F5DA900E16F90 /* MRECAdCell.swift in Sources */, CEEB3549266F5DA900E16F90 /* MRECAdCell.swift in Sources */,
CDB0D4CA2670CAD00081C773 /* ShortsCollectionViewCell.swift in Sources */, CDB0D4CA2670CAD00081C773 /* ShortsCollectionViewCell.swift in Sources */,
CDDCD5092680C18B00E089AD /* ShortsUnreadNudgeView.swift in Sources */, CDDCD5092680C18B00E089AD /* ShortsUnreadNudgeView.swift in Sources */,
CDADBBA726D6552A006E4565 /* MinutelyForecastView.swift in Sources */,
CE13B818262480B3007CBD4D /* A9BidObject.swift in Sources */, CE13B818262480B3007CBD4D /* A9BidObject.swift in Sources */,
CD85796A2671FA8100CC4CDA /* ShortsCoordinator.swift in Sources */, CD85796A2671FA8100CC4CDA /* ShortsCoordinator.swift in Sources */,
CDB0D4CE2670DABF0081C773 /* UIImage+AverageColor.swift in Sources */, CDB0D4CE2670DABF0081C773 /* UIImage+AverageColor.swift in Sources */,
...@@ -1961,11 +1984,11 @@ ...@@ -1961,11 +1984,11 @@
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */, CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */, CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
CDC62C4726C13BE300156643 /* OnboardingContentController.swift in Sources */, CDC62C4726C13BE300156643 /* OnboardingContentController.swift in Sources */,
CD9B6B1125DBC723001D9B80 /* CubicCurveAlgorithm.swift in Sources */,
CD8B60B4263819790055CB3F /* NotificationsViewController.swift in Sources */, CD8B60B4263819790055CB3F /* NotificationsViewController.swift in Sources */,
CD67617026259D220079D273 /* RadarMapLayersController.swift in Sources */, CD67617026259D220079D273 /* RadarMapLayersController.swift in Sources */,
CEC8FBAF2639756A0001A6BF /* OnboardingViewController.swift in Sources */, CEC8FBAF2639756A0001A6BF /* OnboardingViewController.swift in Sources */,
CD866A65260F642600E96A5C /* SettingsDetailsViewController.swift in Sources */, CD866A65260F642600E96A5C /* SettingsDetailsViewController.swift in Sources */,
CDADBBA426D64948006E4565 /* MinutelyForecastCell.swift in Sources */,
CD647D0225ED07D60034578B /* TodayViewModel.swift in Sources */, CD647D0225ED07D60034578B /* TodayViewModel.swift in Sources */,
CD593BD32608BC3F00C93428 /* ForecastDayCell.swift in Sources */, CD593BD32608BC3F00C93428 /* ForecastDayCell.swift in Sources */,
CD8B60AB263819400055CB3F /* NWSAlertCellFactory.swift in Sources */, CD8B60AB263819400055CB3F /* NWSAlertCellFactory.swift in Sources */,
......
...@@ -10,6 +10,7 @@ import UIKit ...@@ -10,6 +10,7 @@ import UIKit
enum TimePeriod: Int { enum TimePeriod: Int {
case daily = 0 case daily = 0
case hourly = 1 case hourly = 1
case minutely = 2
} }
class ForecastTimePeriodControl: UISegmentedControl { class ForecastTimePeriodControl: UISegmentedControl {
......
//
// MinutelyForecastCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.08.2021.
//
import UIKit
class MinutelyForecastCell: UITableViewCell {
private let horizontalStackView = UIStackView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MinutelyForecastView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.08.2021.
//
import UIKit
import OneWeatherCore
enum MinutelyForecastType {
case temperature
case precipitation
}
private class MinutelyLevelView: UIView {
init() {
super.init(frame: .zero)
backgroundColor = .blue
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.width / 2
}
}
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 verticalStackView = UIStackView()
private let scrollView = UIScrollView()
private var location: Location?
init() {
super.init(frame: .zero)
}
override func layoutSubviews() {
super.layoutSubviews()
let leftInset = detailsInfoView.frame.origin.x
scrollView.contentInset = .init(top: 0, left: leftInset, bottom: 0, right: 0)
scrollView.setContentOffset(.init(x: -leftInset, y: 0), animated: false)
}
func configure(with location: Location) {
self.location = location
prepareDetailView()
prepareVerticalStackView()
prepareScrollView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- Prepare
private extension MinutelyForecastView {
func prepareDetailView() {
detailsInfoView.backgroundColor = kTemperatureColors[0]
addSubview(detailsInfoView)
detailsInfoView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.centerX.equalToSuperview()
make.height.equalTo(38)
make.width.equalTo(200)
}
}
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)
make.bottom.equalToSuperview().inset(40)
}
}
func prepareScrollView() {
scrollView.backgroundColor = .red
addSubview(scrollView)
let levelsStackView = UIStackView()
levelsStackView.axis = .horizontal
levelsStackView.spacing = 2
levelsStackView.distribution = .fill
levelsStackView.alignment = .bottom
scrollView.addSubview(levelsStackView)
levelsStackView.snp.makeConstraints { (make) in
make.edges.height.equalToSuperview()
}
scrollView.snp.makeConstraints { make in
make.left.equalTo(verticalStackView.snp.right).offset(6)
make.top.equalTo(detailsInfoView.snp.bottom).offset(8)
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))
}
}
}
}
...@@ -21,6 +21,10 @@ private enum ForecastCellType { ...@@ -21,6 +21,10 @@ private enum ForecastCellType {
case precipitation case precipitation
case wind case wind
//Minutely
case minutely
case precipitationAdviced
// Shared // Shared
case adBanner case adBanner
case adMREC case adMREC
...@@ -168,6 +172,10 @@ class ForecastCellFactory: CellFactory { ...@@ -168,6 +172,10 @@ class ForecastCellFactory: CellFactory {
} }
} }
return cell return cell
case .minutely:
return UITableViewCell()
case .precipitationAdviced:
return UITableViewCell()
} }
} }
...@@ -177,6 +185,8 @@ class ForecastCellFactory: CellFactory { ...@@ -177,6 +185,8 @@ class ForecastCellFactory: CellFactory {
return self.dailySection.rows[indexPath.row] return self.dailySection.rows[indexPath.row]
case .hourly: case .hourly:
return self.hourlySection.rows[indexPath.row] return self.hourlySection.rows[indexPath.row]
default:
return .minutely
} }
} }
...@@ -254,6 +264,8 @@ class ForecastCellFactory: CellFactory { ...@@ -254,6 +264,8 @@ class ForecastCellFactory: CellFactory {
adTypeString = "MREC" adTypeString = "MREC"
adLoggingEmoji = "✅" adLoggingEmoji = "✅"
} }
default:
break
} }
adView.set(placementName: placementName, adType: adType) adView.set(placementName: placementName, adType: adType)
......
...@@ -70,6 +70,8 @@ class ForecastViewController: UIViewController { ...@@ -70,6 +70,8 @@ class ForecastViewController: UIViewController {
analytics(log: .ANALYTICS_VIEW_FORECAST_EXTENDED) analytics(log: .ANALYTICS_VIEW_FORECAST_EXTENDED)
case .hourly: case .hourly:
analytics(log: .ANALYTICS_VIEW_FORECAST_HOURLY) analytics(log: .ANALYTICS_VIEW_FORECAST_HOURLY)
default:
break
} }
} }
......
...@@ -11,8 +11,10 @@ import OneWeatherCore ...@@ -11,8 +11,10 @@ import OneWeatherCore
class TodayForecastTimePeriodCell: UITableViewCell { class TodayForecastTimePeriodCell: UITableViewCell {
//Private //Private
private let periodSegmentedControl = ForecastTimePeriodControl(items: ["forecast.timePeriod.daily".localized(), private let periodSegmentedControl = ForecastTimePeriodControl(items: ["forecast.timePeriod.daily".localized(),
"forecast.timePeriod.hourly".localized()]) "forecast.timePeriod.hourly".localized(),
"forecast.timePeriod.minutely".localized()])
private let forecastTimePeriodView = ForecastTimePeriodView() private let forecastTimePeriodView = ForecastTimePeriodView()
private let minutelyForecastView = MinutelyForecastView()
private let descriptionView = ForecastDescriptionView(lightStyleBackgroundColor: UIColor(hex: 0xfaedda).withAlphaComponent(0.5), private let descriptionView = ForecastDescriptionView(lightStyleBackgroundColor: UIColor(hex: 0xfaedda).withAlphaComponent(0.5),
gradientColors: [UIColor(hex: 0xe81e15).withAlphaComponent(0.33).cgColor, gradientColors: [UIColor(hex: 0xe81e15).withAlphaComponent(0.33).cgColor,
UIColor(hex: 0xf71d11).withAlphaComponent(0).cgColor]) UIColor(hex: 0xf71d11).withAlphaComponent(0).cgColor])
...@@ -26,6 +28,7 @@ class TodayForecastTimePeriodCell: UITableViewCell { ...@@ -26,6 +28,7 @@ class TodayForecastTimePeriodCell: UITableViewCell {
prepareCell() prepareCell()
prepareSegmentedControl() prepareSegmentedControl()
prepareForecastTimePeriodView() prepareForecastTimePeriodView()
prepareMinutelyForecastView()
prepareDescriptionView() prepareDescriptionView()
} }
...@@ -37,6 +40,7 @@ class TodayForecastTimePeriodCell: UITableViewCell { ...@@ -37,6 +40,7 @@ class TodayForecastTimePeriodCell: UITableViewCell {
public func configure(with location:Location) { public func configure(with location:Location) {
self.location = location self.location = location
self.forecastTimePeriodView.set(daily: location.daily, hourly: location.hourly) self.forecastTimePeriodView.set(daily: location.daily, hourly: location.hourly)
self.minutelyForecastView.configure(with: location)
self.handleSegmentDidChange() self.handleSegmentDidChange()
} }
...@@ -45,8 +49,16 @@ class TodayForecastTimePeriodCell: UITableViewCell { ...@@ -45,8 +49,16 @@ class TodayForecastTimePeriodCell: UITableViewCell {
return return
} }
let forecastType = timePeriod == .daily ? ForecastType.daily : ForecastType.hourly switch timePeriod {
self.forecastTimePeriodView.set(forecastType: forecastType, buttonType: ForecastPeriodButton.self) case .daily, .hourly:
forecastTimePeriodView.isHidden = false
minutelyForecastView.isHidden = true
let forecastType = timePeriod == .daily ? ForecastType.daily : ForecastType.hourly
self.forecastTimePeriodView.set(forecastType: forecastType, buttonType: ForecastPeriodButton.self)
case .minutely:
forecastTimePeriodView.isHidden = true
minutelyForecastView.isHidden = false
}
} }
} }
...@@ -78,6 +90,18 @@ private extension TodayForecastTimePeriodCell { ...@@ -78,6 +90,18 @@ private extension TodayForecastTimePeriodCell {
} }
} }
func prepareMinutelyForecastView() {
minutelyForecastView.isHidden = true
contentView.addSubview(minutelyForecastView)
minutelyForecastView.snp.makeConstraints { (make) in
make.left.equalToSuperview()
make.right.equalToSuperview()
make.top.equalTo(periodSegmentedControl.snp.bottom).offset(40).priority(.medium)
make.height.equalTo(240)
}
}
func prepareDescriptionView() { func prepareDescriptionView() {
//TODO: Hide the description for now //TODO: Hide the description for now
descriptionView.isHidden = true descriptionView.isHidden = true
......
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