Commit 24b1d100 by Dmitry Stepanets

[iOS-154]: Finished precipitation minutely forecast

parent 68b65e12
......@@ -108,20 +108,23 @@ private extension MinutelyForecastDetailsView {
separator.snp.makeConstraints { make in
make.width.equalTo(1)
make.height.equalToSuperview().multipliedBy(0.65)
make.right.equalTo(tempLabel.snp.left).offset(-6)
make.left.equalToSuperview().inset(70)
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(8)
}
tempLabel.snp.makeConstraints { make in
make.right.equalTo(forecastImage.snp.left).offset(-2)
make.centerY.equalToSuperview()
}
}
func prepareTriangle() {
......
......@@ -114,6 +114,7 @@ private class SwipeNudgeView: UIView {
class MinutelyForecastView: UIView {
//Private
private let kLevelWidth = 3
private let kScrollViewRightInset: CGFloat = 20
private let detailsInfoView = MinutelyForecastDetailsView()
private let swipeNudgeView = SwipeNudgeView()
private let levelsStackView = UIStackView()
......@@ -159,7 +160,7 @@ class MinutelyForecastView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
let leftInset = detailsInfoView.frame.origin.x - scrollView.frame.origin.x + detailsInfoView.frame.width / 2
let leftInset = (scrollView.bounds.width - kScrollViewRightInset) / 2
if scrollView.contentInset.left != leftInset {
scrollView.contentInset = .init(top: 0, left: leftInset, bottom: 0, right: leftInset + 20)
scrollView.setContentOffset(.init(x: -leftInset, y: 0), animated: false)
......@@ -229,7 +230,7 @@ class MinutelyForecastView: UIView {
timeZone: location?.timeZone ?? .current,
colors: kTemperatureColors)
case .precipitation:
self.detailsInfoView.configure(valueStirng: "\(Int(minutelyItem.precipitation * 100))%",
self.detailsInfoView.configure(valueStirng: minutelyItem.precipitation.settingsConverted.string,
date: minutelyItem.time,
weatherImage: minutelyItem.weatherTypeImage,
timeZone: location?.timeZone ?? .current,
......@@ -361,14 +362,14 @@ class MinutelyForecastView: UIView {
private func updatePrecipitationChart() {
guard
let maxPrecip = (minutelyForecast.compactMap{ $0.precipitation }.max{ $0 < $1 }),
let minPrecip = (minutelyForecast.compactMap{ $0.precipitation }.min{ $0 < $1 })
let maxPrecip = (minutelyForecast.compactMap{ $0.precipitation }.max{ $0.settingsConvertedValue < $1.settingsConvertedValue }),
let minPrecip = (minutelyForecast.compactMap{ $0.precipitation }.min{ $0.settingsConvertedValue < $1.settingsConvertedValue })
else {
return
}
var uniqPrecips = minutelyForecast.compactMap{ $0.precipitation }.unique().sorted{$0 > $1}
var uniqPrecips = minutelyForecast.compactMap{ $0.precipitation }.unique().sorted{$0.settingsConvertedValue > $1.settingsConvertedValue}
if uniqPrecips.count > 4 {
let uniqMax = uniqPrecips.removeFirst()
let uniqMin = uniqPrecips.removeLast()
......@@ -384,7 +385,7 @@ class MinutelyForecastView: UIView {
for precipitation in uniqPrecips {
let label = UILabel()
label.text = "\(Int(precipitation * 100))%"
label.text = precipitation.settingsConverted.shortString
label.font = AppFont.SFPro.regular(size: 10)
label.setContentHuggingPriority(.fittingSizeLevel, for: .vertical)
label.sizeToFit()
......@@ -394,8 +395,9 @@ class MinutelyForecastView: UIView {
for index in 0..<minutelyForecast.count {
let view = MinutelyLevelView(forecastType: .precipitation)
levelsStackView.addArrangedSubview(view)
let diff = maxPrecip - minPrecip == 0 ? 1 : maxPrecip - minPrecip
let level = (0.05 + 0.9 * ((minutelyForecast[index].precipitation - minPrecip) / diff))
let diff = maxPrecip.settingsConvertedValue - minPrecip.settingsConvertedValue == 0 ? 1
: maxPrecip.settingsConvertedValue - minPrecip.settingsConvertedValue
let level = (0.05 + 0.9 * ((minutelyForecast[index].precipitation.settingsConvertedValue - minPrecip.settingsConvertedValue) / diff))
view.snp.makeConstraints { make in
make.width.equalTo(kLevelWidth)
make.height.equalToSuperview().multipliedBy(level)
......@@ -444,7 +446,6 @@ private extension MinutelyForecastView {
//Constraints
detailsInfoView.snp.makeConstraints { make in
make.width.equalTo(158)
make.height.equalTo(50)
make.top.equalToSuperview()
make.centerX.equalToSuperview()
......@@ -483,7 +484,7 @@ private extension MinutelyForecastView {
scrollView.snp.makeConstraints { make in
make.left.equalToSuperview().inset(42)
make.top.equalTo(detailsInfoView.snp.bottom).offset(8)
make.right.equalToSuperview().inset(20)
make.right.equalToSuperview().inset(kScrollViewRightInset)
make.bottom.equalToSuperview().inset(40)
}
}
......
......@@ -72,6 +72,8 @@ class SettingsDetailsViewModel: ViewModelProtocol {
Settings.shared.pressureType = pressures[index]
case .distance:
Settings.shared.distanceType = distances[index]
case .rainfall:
Settings.shared.rainfallType = rainFalls[index]
default:
break
}
......
......@@ -21,6 +21,15 @@ public extension Measurement {
return fmt
}
private static func fractionFormatter(style: Formatter.UnitStyle, unitOptions: MeasurementFormatter.UnitOptions = .providedUnit) -> MeasurementFormatter {
let fmt = MeasurementFormatter.oneWeatherSharedFormatter
fmt.locale = Settings.shared.locale
fmt.unitStyle = style
fmt.unitOptions = unitOptions
fmt.numberFormatter.maximumFractionDigits = 2
return fmt
}
var string:String {
return Measurement.formatter(style: .medium).string(from: self)
}
......@@ -78,3 +87,21 @@ public extension Pressure {
}
}
public extension Rainfall {
var settingsConvertedValue: Double {
return self.converted(to: Settings.shared.rainfallType).value
}
var settingsConverted: Measurement {
return self.converted(to: Settings.shared.rainfallType)
}
var string:String {
return Measurement.fractionFormatter(style: .medium).string(from: self)
}
var shortString: String {
return String(format: "%.2f", self.value)
}
}
......@@ -343,11 +343,14 @@ public enum MoonPhase: String, Codable {
}
}
public class UnitRainfall: Dimension {
public final class UnitRainfall: Dimension {
public static let inchesPerHour = UnitRainfall(symbol: "in/h", converter: UnitConverterLinear(coefficient: 1.0))
public static let millimetersPerHour = UnitRainfall(symbol: "mm/h", converter: UnitConverterLinear(coefficient: 25.4))
public static let millimetersPerHour = UnitRainfall(symbol: "mm/h", converter: UnitConverterLinear(coefficient: 0.03937))
public static let baseUnit = UnitRainfall.inchesPerHour
public override class func baseUnit() -> UnitRainfall {
return inchesPerHour
}
}
public struct Time: CustomStringConvertible, Codable {
......
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