Commit b8dd6f8e by Dmitriy Stepanets

Finished moon phase cell. Working on additional graph line.

parent 6a391ad4
......@@ -42,6 +42,9 @@
CDC6124F25E7964700188DA7 /* CityDayTimesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6124E25E7964700188DA7 /* CityDayTimesCell.swift */; };
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125225E79C8F00188DA7 /* DayTimeView.swift */; };
CDC6125725E7AB1A00188DA7 /* CityAirQualityCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6125625E7AB1A00188DA7 /* CityAirQualityCell.swift */; };
CDC6126225E8DAB800188DA7 /* CityMoonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6126125E8DAB800188DA7 /* CityMoonCell.swift */; };
CDC6126625E9085600188DA7 /* GraphLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6126525E9085600188DA7 /* GraphLine.swift */; };
CDC6126A25E90C8800188DA7 /* GraphLineSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC6126925E90C8800188DA7 /* GraphLineSettings.swift */; };
CDD0F1E52572425200CF5017 /* SF-Pro.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CDD0F1E42572425200CF5017 /* SF-Pro.ttf */; };
CDD0F1E82572429E00CF5017 /* AppFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD0F1E72572429E00CF5017 /* AppFont.swift */; };
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */; };
......@@ -94,6 +97,9 @@
CDC6124E25E7964700188DA7 /* CityDayTimesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityDayTimesCell.swift; sourceTree = "<group>"; };
CDC6125225E79C8F00188DA7 /* DayTimeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimeView.swift; sourceTree = "<group>"; };
CDC6125625E7AB1A00188DA7 /* CityAirQualityCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityAirQualityCell.swift; sourceTree = "<group>"; };
CDC6126125E8DAB800188DA7 /* CityMoonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityMoonCell.swift; sourceTree = "<group>"; };
CDC6126525E9085600188DA7 /* GraphLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphLine.swift; sourceTree = "<group>"; };
CDC6126925E90C8800188DA7 /* GraphLineSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphLineSettings.swift; sourceTree = "<group>"; };
CDD0F1E42572425200CF5017 /* SF-Pro.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro.ttf"; sourceTree = "<group>"; };
CDD0F1E72572429E00CF5017 /* AppFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppFont.swift; sourceTree = "<group>"; };
CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
......@@ -238,6 +244,7 @@
CDEE8AD425DA87DD00C289DE /* CityForecastTimePeriod */,
CD86246325E66E6B0097F3FB /* CityPrecipCell */,
CD86245B25E646000097F3FB /* CitySunCell */,
CDC6126025E8DA2900188DA7 /* CityMoonCell */,
CDC6124D25E7960D00188DA7 /* CityDayTimesCell */,
CDC6125525E7AAF600188DA7 /* CityAirQualityCell */,
CD822FF425D6817000A05501 /* CityForecastCell.swift */,
......@@ -291,6 +298,14 @@
path = CityAirQualityCell;
sourceTree = "<group>";
};
CDC6126025E8DA2900188DA7 /* CityMoonCell */ = {
isa = PBXGroup;
children = (
CDC6126125E8DAB800188DA7 /* CityMoonCell.swift */,
);
path = CityMoonCell;
sourceTree = "<group>";
};
CDD0F1DC2572400200CF5017 /* UI */ = {
isa = PBXGroup;
children = (
......@@ -330,7 +345,9 @@
CDD0F1ED25725BCF00CF5017 /* ThemeManager.swift */,
CD9B6B1025DBC723001D9B80 /* CubicCurveAlgorithm.swift */,
CD9B6B1325DBCDE2001D9B80 /* GraphView.swift */,
CDC6126525E9085600188DA7 /* GraphLine.swift */,
CD86246B25E6826A0097F3FB /* InnerShadowLayer.swift */,
CDC6126925E90C8800188DA7 /* GraphLineSettings.swift */,
);
path = Helpers;
sourceTree = "<group>";
......@@ -506,6 +523,7 @@
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */,
CD86246925E672A20097F3FB /* PrecipButton.swift in Sources */,
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */,
CDC6126225E8DAB800188DA7 /* CityMoonCell.swift in Sources */,
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
CD9B6B1125DBC723001D9B80 /* CubicCurveAlgorithm.swift in Sources */,
......@@ -514,11 +532,13 @@
CD86246125E662BC0097F3FB /* SunUvLineView.swift in Sources */,
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */,
CDE18DCD25D1666700C80ED9 /* ForecastCoordinator.swift in Sources */,
CDC6126625E9085600188DA7 /* GraphLine.swift in Sources */,
CD86246525E66E8A0097F3FB /* CityPrecipCell.swift in Sources */,
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */,
CD17C5F625D15B4400EE884E /* TodayViewController.swift in Sources */,
CD86245E25E646350097F3FB /* SunUvView.swift in Sources */,
CD82300725D6A73F00A05501 /* CityConditionButton.swift in Sources */,
CDC6126A25E90C8800188DA7 /* GraphLineSettings.swift in Sources */,
CD86246C25E6826A0097F3FB /* InnerShadowLayer.swift in Sources */,
CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */,
);
......
......@@ -7,7 +7,7 @@
<key>1Weather.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
<integer>5</integer>
</dict>
<key>PG (Playground) 1.xcscheme</key>
<dict>
......
{
"images" : [
{
"filename" : "moon_down_arrow.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "moon_path_waxingGibbous.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "moon_up_arrow.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "moon_waxingGibbous.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
......@@ -37,7 +37,14 @@
//Moon
"moon.title" = "moon";
"moon.newMoon" = "New Moon";
"moon.phase.new" = "New Moon";
"moon.phase.waxingCrescent" = "Waxing Crescent";
"moon.phase.firstQuarter" = "First Quarter";
"moon.phase.waxingGibbous" = "Waxing Gibbous";
"moon.phase.fullMoon" = "Full Moon";
"moon.phase.waningGibbous" = "Waning Gibbous";
"moon.phase.thirdQuarter" = "Third Quarter";
"moon.phase.wanningCrescent" = "Waning Crescent";
//Precipitation
"precipitation.title" = "precipitation";
......
//
// GraphLine.swift
// 1Weather
//
// Created by Dmitry Stepanets on 26.02.2021.
//
import UIKit
import BezierKit
struct LineDot {
let center:CGPoint
let shape:CAShapeLayer
}
struct GraphLine {
//Private
private static let cubicCurveAlgorithm = CubicCurveAlgorithm()
private let kIntersectAccuracy:CGFloat = 2
private let points:[CGPoint]
private let tintColor:UIColor
private let graphViewRect:CGRect
private var sections = [CubicCurve]()
//Public
let lineShape = CAShapeLayer()
private(set) var tintLineShape = CAShapeLayer()
private(set) var lineDots = [LineDot]()
init(graphViewRect:CGRect, points:[CGPoint], settings:GraphLineSettings) {
self.graphViewRect = graphViewRect
self.points = points
self.tintColor = settings.tintColor
//Line
lineShape.path = self.linePath(from: points).cgPath
lineShape.fillColor = UIColor.clear.cgColor
lineShape.strokeColor = settings.color.cgColor
lineShape.lineWidth = settings.lineWidth
lineShape.lineCap = .round
lineShape.lineJoin = .round
//Shadow
lineShape.shadowColor = UIColor.black.cgColor
lineShape.shadowOffset = .init(width: 0, height: 6)
lineShape.shadowRadius = 3
lineShape.shadowOpacity = 0.1
//Tint line
tintLineShape.fillColor = UIColor.clear.cgColor
tintLineShape.strokeColor = settings.tintColor.cgColor
tintLineShape.lineWidth = settings.lineWidth
tintLineShape.lineCap = .round
tintLineShape.lineJoin = .round
tintLineShape.path = nil
//Dots
self.points.forEach {
let dotShape = CAShapeLayer()
dotShape.path = UIBezierPath(arcCenter: $0,
radius: settings.dotRadius,
startAngle: 0,
endAngle: .pi * 2,
clockwise: true).cgPath
dotShape.fillColor = UIColor.white.cgColor
dotShape.strokeColor = settings.color.cgColor
dotShape.lineWidth = settings.dotLineWidth
lineDots.append(.init(center: $0, shape: dotShape))
}
}
private mutating func linePath(from points:[CGPoint]) -> UIBezierPath {
let path = UIBezierPath()
let startPoint = CGPoint(x: 0, y: self.graphViewRect.height)
let endPoint = CGPoint(x: self.graphViewRect.width, y: self.graphViewRect.height)
var pointsToAdd = [CGPoint]()
pointsToAdd.append(startPoint)
pointsToAdd.append(contentsOf: points)
pointsToAdd.append(endPoint)
path.move(to: pointsToAdd.first!)
if pointsToAdd.count == 2 {
path.addLine(to: points[1])
return path
}
let controlPoints = GraphLine.cubicCurveAlgorithm.controlPointsFromPoints(dataPoints: pointsToAdd)
for index in 1..<pointsToAdd.count {
sections.append(.init(p0: pointsToAdd[index - 1],
p1: controlPoints[index - 1].controlPoint1,
p2: controlPoints[index - 1].controlPoint2,
p3: pointsToAdd[index]))
path.addCurve(to: pointsToAdd[index],
controlPoint1: controlPoints[index - 1].controlPoint1,
controlPoint2: controlPoints[index - 1].controlPoint2)
}
return path
}
//Public
func tintLineFrom(startPointX:CGFloat, to endPointX:CGFloat) {
func getSubcurvePath(baseCurve:CubicCurve, leftBoundary:LineSegment, rightBoundary:LineSegment) -> UIBezierPath? {
guard
let leftIntersection = baseCurve.intersections(with: leftBoundary).first,
let rightIntersection = baseCurve.intersections(with: rightBoundary).first
else {
return nil
}
let subcurve = baseCurve.split(from: leftIntersection.t1, to: rightIntersection.t1)
let path = UIBezierPath()
path.move(to: subcurve.startingPoint)
path.addCurve(to: subcurve.endingPoint, controlPoint1: subcurve.p1, controlPoint2: subcurve.p2)
return path
}
let leftLine = LineSegment(p0: .init(x: startPointX + kIntersectAccuracy, y: 0),
p1: .init(x: startPointX + kIntersectAccuracy, y: self.graphViewRect.height))
let rightLine = LineSegment(p0: .init(x: endPointX - kIntersectAccuracy, y: 0),
p1: .init(x: endPointX - kIntersectAccuracy, y: self.graphViewRect.height))
//Get all sections for the given tint and cut them
let tintPath = UIBezierPath()
for section in sections {
if section.startingPoint.x >= leftLine.p0.x || section.endingPoint.x <= rightLine.p0.x {
let maxLeftPointX = max(section.startingPoint.x, leftLine.startingPoint.x)
let minRightPointX = min(section.endingPoint.x, rightLine.endingPoint.x)
let leftBoundary = LineSegment(p0: .init(x: maxLeftPointX, y: 0),
p1: .init(x: maxLeftPointX, y: self.graphViewRect.height))
let rightBoundary = LineSegment(p0: .init(x: minRightPointX, y: 0),
p1: .init(x: minRightPointX, y: self.graphViewRect.height))
if let subcurve = getSubcurvePath(baseCurve: section,
leftBoundary: leftBoundary,
rightBoundary: rightBoundary)
{
tintPath.append(subcurve)
}
}
}
//Check for empty path
if tintPath.isEmpty { return }
tintLineShape.path = tintPath.cgPath
}
func tintDotAt(point:CGPoint) {
lineDots.forEach {
$0.shape.strokeColor = ThemeManager.currentTheme.graphColor.cgColor
}
guard let dotToTint = (lineDots.first{$0.center == point}) else { return }
dotToTint.shape.strokeColor = ThemeManager.currentTheme.graphTintColor.cgColor
}
}
//
// GraphLineSettings.swift
// 1Weather
//
// Created by Dmitry Stepanets on 26.02.2021.
//
import UIKit
struct GraphLineSettings {
//Line
let lineWidth:CGFloat
//Dot
let dotRadius:CGFloat
let dotLineWidth:CGFloat
//General
let color:UIColor
let tintColor:UIColor
}
......@@ -8,11 +8,6 @@
import UIKit
import BezierKit
private struct GraphDot {
let center:CGPoint
let shape:CAShapeLayer
}
class GraphView: UIView {
//Private
private let kIntersectAccuracy:CGFloat = 2
......@@ -21,7 +16,7 @@ class GraphView: UIView {
private let graphTintColor:UIColor
private let lineShape = CAShapeLayer()
private let tintShape = CAShapeLayer()
private var lineDots = [GraphDot]()
private var lineDots = [LineDot]()
private let cubicCurveAlgorithm = CubicCurveAlgorithm()
private var sections = [CubicCurve]()
......
//
// CityMoonCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 26.02.2021.
//
import UIKit
class CityMoonCell: UITableViewCell {
static let kIdentifier = "cityMoonCell"
//Private
private let kCircleInset:CGFloat = 55
private let headingLabel = UILabel()
private let headingButton = ArrowButton()
private let container = UIView()
private let infoLabel = UILabel()
private let baseLine = UIView()
private let moonUpImageView = UIImageView()
private let moonUpTimeLabel = UILabel()
private let moonDownImageView = UIImageView()
private let moonDownTimeLabel = UILabel()
private let circleGradientLayer = CAGradientLayer()
private let moonImageView = UIImageView()
private let moonTypeImageView = UIImageView()
private let moonTypeLabel = UILabel()
//MARK:- Cell life cycle
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
prepareCell()
prepareHeading()
prepareContainer()
prepareInfoLabel()
prepareMoonViews()
prepareMoonCirle()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: baseLine.frame.origin.x + baseLine.bounds.width / 2, y: baseLine.frame.origin.y)
let radius = center.x - kCircleInset
//Gradient
circleGradientLayer.frame = .init(x: kCircleInset - 4,
y: center.y - radius - 4,
width: (radius * 2) + 8,
height: radius + 4)
let circlePath = UIBezierPath(arcCenter: .init(x: circleGradientLayer.frame.width / 2,
y: circleGradientLayer.frame.height),
radius: (circleGradientLayer.frame.width / 2) - 4,
startAngle: 0,
endAngle: .pi,
clockwise: false)
let mask = CAShapeLayer()
mask.fillRule = .evenOdd
mask.fillColor = UIColor.clear.cgColor
mask.strokeColor = UIColor.black.cgColor
mask.lineWidth = 4
mask.path = circlePath.cgPath
circleGradientLayer.mask = mask
}
//Private
@objc private func handleHeadingButton() {
}
private func moonPath(progress:CGFloat) -> UIBezierPath {
var pathProgress = max(0, progress)
pathProgress = min(1, pathProgress)
let start:CGFloat = -.pi
let end:CGFloat = 0
let percent = (start - end) * pathProgress
let center = CGPoint(x: baseLine.frame.origin.x + baseLine.bounds.width / 2, y: baseLine.frame.origin.y)
let radius = center.x - kCircleInset
let path = UIBezierPath(arcCenter: center,
radius: radius,
startAngle: start,
endAngle: start - percent,
clockwise: true)
return path
}
//Public
public func updateMoonPosition() {
moonImageView.layer.removeAnimation(forKey: "moon.position")
moonImageView.frame.origin = .init(x: kCircleInset - moonImageView.frame.width / 2,
y: baseLine.frame.origin.y - moonImageView.frame.height)
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = self.moonPath(progress: 0.7).cgPath
animation.calculationMode = .paced
animation.duration = 1.3
animation.rotationMode = .rotateAuto
animation.isRemovedOnCompletion = false
animation.fillMode = .forwards
moonImageView.layer.add(animation, forKey: "moon.position")
}
}
//MARK:- Prepare
private extension CityMoonCell {
func prepareCell() {
selectionStyle = .none
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
}
func prepareHeading() {
//Label
headingLabel.font = AppFont.SFPro.bold(size: 16)
headingLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
headingLabel.text = "moon.title".localized().uppercased()
contentView.addSubview(headingLabel)
headingLabel.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(18)
make.top.equalToSuperview().inset(15)
}
//Arrow button
headingButton.addTarget(self, action: #selector(handleHeadingButton), for: .touchUpInside)
contentView.addSubview(headingButton)
headingButton.snp.makeConstraints { (make) in
make.width.height.equalTo(30)
make.right.equalToSuperview().inset(18)
make.centerY.equalTo(headingLabel)
}
}
func prepareContainer() {
container.backgroundColor = UIColor(hex: 0xECEEF6)
container.layer.cornerRadius = 12
contentView.addSubview(container)
container.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(18)
make.top.equalTo(headingLabel.snp.bottom).offset(18)
make.bottom.equalToSuperview().inset(15)
make.height.equalTo(290)
}
}
func prepareInfoLabel() {
infoLabel.numberOfLines = 0
infoLabel.lineBreakMode = .byWordWrapping
infoLabel.text = "Tides are higher than usual due to new moon"
infoLabel.font = AppFont.SFPro.regular(size: 16)
infoLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
container.addSubview(infoLabel)
infoLabel.snp.makeConstraints { (make) in
make.left.top.right.equalToSuperview().inset(18)
}
}
func prepareMoonViews() {
//Base line
baseLine.backgroundColor = UIColor(hex: 0xc2c9d6)
baseLine.alpha = 0.47
container.addSubview(baseLine)
baseLine.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(2)
make.height.equalTo(2)
make.bottom.equalToSuperview().inset(52)
}
//Up arrow
moonUpImageView.contentMode = .scaleAspectFit
moonUpImageView.image = UIImage(named: "moon_up_arrow")
moonUpImageView.tintColor = UIColor(hex: 0x1f67f3)
container.addSubview(moonUpImageView)
moonUpImageView.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(22)
make.bottom.equalTo(baseLine.snp.top).offset(-20)
}
//Down arrow
moonDownImageView.contentMode = .scaleAspectFit
moonDownImageView.image = UIImage(named: "moon_down_arrow")
moonDownImageView.tintColor = UIColor(hex: 0x1f67f3)
container.addSubview(moonDownImageView)
moonDownImageView.snp.makeConstraints { (make) in
make.right.equalToSuperview().inset(22)
make.bottom.equalTo(baseLine.snp.top).offset(-20)
}
//Type
moonTypeImageView.contentMode = .scaleAspectFit
moonTypeImageView.image = UIImage(named: "moon_waxingGibbous")
container.addSubview(moonTypeImageView)
moonTypeImageView.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.bottom.equalTo(baseLine.snp.top).offset(-56)
make.width.height.equalTo(30)
}
moonTypeLabel.font = AppFont.SFPro.regular(size: 14)
moonTypeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
moonTypeLabel.text = "moon.phase.waxingGibbous".localized()
container.addSubview(moonTypeLabel)
moonTypeLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalTo(moonTypeImageView.snp.bottom).offset(17)
}
//Times
moonUpTimeLabel.font = AppFont.SFPro.bold(size: 14)
moonUpTimeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
moonUpTimeLabel.text = "6:11 AM"
moonUpTimeLabel.textAlignment = .left
container.addSubview(moonUpTimeLabel)
moonUpTimeLabel.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(20)
make.top.equalTo(baseLine.snp.bottom).offset(18)
}
moonDownTimeLabel.font = AppFont.SFPro.bold(size: 14)
moonDownTimeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
moonDownTimeLabel.text = "5:47 PM"
moonDownTimeLabel.textAlignment = .right
container.addSubview(moonDownTimeLabel)
moonDownTimeLabel.snp.makeConstraints { (make) in
make.right.equalToSuperview().inset(20)
make.top.equalTo(baseLine.snp.bottom).offset(18)
}
}
func prepareMoonCirle() {
circleGradientLayer.colors = [UIColor(hex: 0x416bff).cgColor, UIColor(hex: 0x10bcff).cgColor]
circleGradientLayer.startPoint = .init(x: 0.5, y: 0)
circleGradientLayer.endPoint = .init(x: 0.5, y: 1)
container.layer.addSublayer(circleGradientLayer)
moonImageView.image = UIImage(named: "moon_path_waxingGibbous")
moonImageView.contentMode = .scaleAspectFit
moonImageView.frame = .init(x: 0, y: 0, width: 28, height: 28)
container.addSubview(moonImageView)
}
}
......@@ -14,14 +14,14 @@ private enum TodayTableCell {
case forecastPeriod
case precipitation
case dayTime
case aqi
case sun
case moon
}
class TodayViewController: UIViewController {
//Private
private let tableView = UITableView()
private let tableCells:[TodayTableCell] = [.forecast, .ad, .conditions, .forecastPeriod, .precipitation, .dayTime, .aqi, .sun]
private let tableCells:[TodayTableCell] = [.forecast, .ad, .conditions, .forecastPeriod, .precipitation, .dayTime, .sun, .moon]
private var localizationObserver:Any?
deinit {
......@@ -94,6 +94,8 @@ private extension TodayViewController {
tableView.register(CityDayTimesCell.self, forCellReuseIdentifier: CityDayTimesCell.kIdentifier)
tableView.register(CityAirQualityCell.self, forCellReuseIdentifier: CityAirQualityCell.kIdentifier)
tableView.register(CitySunCell.self, forCellReuseIdentifier: CitySunCell.kIdentifier)
tableView.register(CityMoonCell.self, forCellReuseIdentifier: CityMoonCell.kIdentifier)
tableView.contentInset = .init(top: 0, left: 0, bottom: 15, right: 0)
tableView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
tableView.separatorStyle = .none
tableView.tableFooterView = UIView()
......@@ -135,12 +137,12 @@ extension TodayViewController: UITableViewDataSource {
case .dayTime:
let cell = tableView.dequeueReusableCell(withIdentifier: CityDayTimesCell.kIdentifier, for: indexPath) as! CityDayTimesCell
return cell
case .aqi:
let cell = tableView.dequeueReusableCell(withIdentifier: CityAirQualityCell.kIdentifier, for: indexPath) as! CityAirQualityCell
return cell
case .sun:
let cell = tableView.dequeueReusableCell(withIdentifier: CitySunCell.kIdentifier, for: indexPath) as! CitySunCell
return cell
case .moon:
let cell = tableView.dequeueReusableCell(withIdentifier: CityMoonCell.kIdentifier, for: indexPath) as! CityMoonCell
return cell
}
}
}
......@@ -155,5 +157,9 @@ extension TodayViewController: UITableViewDelegate {
if let sunCell = cell as? CitySunCell {
sunCell.updateSunPosition()
}
if let moonCell = cell as? CityMoonCell {
moonCell.updateMoonPosition()
}
}
}
......@@ -9,35 +9,35 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>1</integer>
<integer>0</integer>
</dict>
<key>Cirque.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>1</integer>
</dict>
<key>Localize-Swift.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>2</integer>
</dict>
<key>Pods-1Weather.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
<integer>3</integer>
</dict>
<key>SnapKit.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>5</integer>
<integer>4</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
......
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