Commit f7e7ac00 by Dmitriy Stepanets

Finished sun cell

parent 4b7269bf
......@@ -32,6 +32,8 @@
CD82300325D69DE400A05501 /* CityConditionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300225D69DE400A05501 /* CityConditionsCell.swift */; };
CD82300725D6A73F00A05501 /* CityConditionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300625D6A73E00A05501 /* CityConditionButton.swift */; };
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300925D6B2AF00A05501 /* AppTabBarController.swift */; };
CD86245E25E646350097F3FB /* SunUvView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD86245D25E646350097F3FB /* SunUvView.swift */; };
CD86246125E662BC0097F3FB /* SunUvLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD86246025E662BC0097F3FB /* SunUvLineView.swift */; };
CD9B6B1125DBC723001D9B80 /* CubicCurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9B6B1025DBC723001D9B80 /* CubicCurveAlgorithm.swift */; };
CD9B6B1425DBCDE2001D9B80 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9B6B1325DBCDE2001D9B80 /* GraphView.swift */; };
CDD0F1E52572425200CF5017 /* SF-Pro.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CDD0F1E42572425200CF5017 /* SF-Pro.ttf */; };
......@@ -76,6 +78,8 @@
CD82300225D69DE400A05501 /* CityConditionsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityConditionsCell.swift; sourceTree = "<group>"; };
CD82300625D6A73E00A05501 /* CityConditionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CityConditionButton.swift; sourceTree = "<group>"; };
CD82300925D6B2AF00A05501 /* AppTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTabBarController.swift; sourceTree = "<group>"; };
CD86245D25E646350097F3FB /* SunUvView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SunUvView.swift; sourceTree = "<group>"; };
CD86246025E662BC0097F3FB /* SunUvLineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SunUvLineView.swift; sourceTree = "<group>"; };
CD9B6B1025DBC723001D9B80 /* CubicCurveAlgorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CubicCurveAlgorithm.swift; sourceTree = "<group>"; };
CD9B6B1325DBCDE2001D9B80 /* GraphView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
CDD0F1E42572425200CF5017 /* SF-Pro.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-Pro.ttf"; sourceTree = "<group>"; };
......@@ -220,9 +224,9 @@
children = (
CD82300125D69DB900A05501 /* CityConditions */,
CDEE8AD425DA87DD00C289DE /* CityForecastTimePeriod */,
CD86245B25E646000097F3FB /* CitySunCell */,
CD822FF425D6817000A05501 /* CityForecastCell.swift */,
CD822FFD25D6976F00A05501 /* TodayAdCell.swift */,
CD39F2F125DE94C4009FE398 /* CitySunCell.swift */,
);
path = Cells;
sourceTree = "<group>";
......@@ -236,6 +240,16 @@
path = CityConditions;
sourceTree = "<group>";
};
CD86245B25E646000097F3FB /* CitySunCell */ = {
isa = PBXGroup;
children = (
CD39F2F125DE94C4009FE398 /* CitySunCell.swift */,
CD86245D25E646350097F3FB /* SunUvView.swift */,
CD86246025E662BC0097F3FB /* SunUvLineView.swift */,
);
path = CitySunCell;
sourceTree = "<group>";
};
CDD0F1DC2572400200CF5017 /* UI */ = {
isa = PBXGroup;
children = (
......@@ -451,10 +465,12 @@
CD9B6B1125DBC723001D9B80 /* CubicCurveAlgorithm.swift in Sources */,
CD15DB4225DA806C00024727 /* CityForecastTimePeriodCell.swift in Sources */,
CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */,
CD86246125E662BC0097F3FB /* SunUvLineView.swift in Sources */,
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */,
CDE18DCD25D1666700C80ED9 /* ForecastCoordinator.swift in Sources */,
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */,
CD17C5F625D15B4400EE884E /* TodayViewController.swift in Sources */,
CD86245E25E646350097F3FB /* SunUvView.swift in Sources */,
CD82300725D6A73F00A05501 /* CityConditionButton.swift in Sources */,
CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */,
);
......
{
"images" : [
{
"filename" : "sun_down_arrow.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "sun_up_arrow.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
......@@ -6,8 +6,8 @@
"components" : {
"alpha" : "1.000",
"blue" : "105",
"green" : "77",
"red" : "68"
"green" : "79",
"red" : "70"
}
},
"idiom" : "universal"
......@@ -24,8 +24,8 @@
"components" : {
"alpha" : "1.000",
"blue" : "105",
"green" : "77",
"red" : "68"
"green" : "79",
"red" : "70"
}
},
"idiom" : "universal"
......
......@@ -45,6 +45,8 @@ class CitySunCell: UITableViewCell {
private let sunActivityContainer = UIView()
private let sunActivityStartLabel = UILabel()
private let sunActivityEndLabel = UILabel()
private let sunUvLineView = SunUvLineView()
private let sunUvView = SunUvView()
private let maxUvLabel = UILabel()
//Computed
......@@ -100,6 +102,21 @@ class CitySunCell: UITableViewCell {
return path
}
private func setUV(level:Int) {
sunUvView.set(uvLevel: level)
//Label
let maxUvText = "sun.maxUV".localized()
let levelText = "\(level)"
let attrStirng = NSMutableAttributedString(string: "\(maxUvText): \(level)",
attributes: [.foregroundColor : ThemeManager.currentTheme.secondaryTextColor,
.kern : 0.19,
.font : AppFont.SFPro.regular(size: 14)])
attrStirng.addAttributes([.font : AppFont.SFPro.bold(size: 14)],
range: NSRange(location: maxUvText.count + 2, length: levelText.count))
maxUvLabel.attributedText = attrStirng
}
@objc private func handleArrowButton() {
}
......@@ -201,7 +218,6 @@ private extension CitySunCell {
}
func prepareSunActivityContainer() {
sunActivityContainer.isHidden = true
sunActivityContainer.clipsToBounds = false
sunActivityContainer.backgroundColor = .white
sunActivityContainer.layer.cornerRadius = 12
......@@ -214,8 +230,73 @@ private extension CitySunCell {
sunActivityContainer.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(18)
make.top.equalTo(infographicContainer.snp.bottom).offset(10)
make.height.equalTo(100)
make.bottom.equalToSuperview().inset(15)
}
//Start
let sunUpImageView = UIImageView(image: UIImage(named: "sun_up_arrow"))
sunUpImageView.contentMode = .scaleAspectFit
sunUpImageView.tintColor = ThemeManager.currentTheme.secondaryTextColor
sunActivityStartLabel.font = AppFont.SFPro.regular(size: 14)
sunActivityStartLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
sunActivityStartLabel.text = "6:11 AM"
sunActivityStartLabel.textAlignment = .left
sunActivityContainer.addSubview(sunUpImageView)
sunActivityContainer.addSubview(sunActivityStartLabel)
sunUpImageView.snp.makeConstraints { (make) in
make.left.top.equalToSuperview().inset(20)
}
sunActivityStartLabel.snp.makeConstraints { (make) in
make.left.equalTo(sunUpImageView.snp.right).offset(3)
make.centerY.equalTo(sunUpImageView)
}
//End
let sunDownImageView = UIImageView(image: UIImage(named: "sun_down_arrow"))
sunDownImageView.contentMode = .scaleAspectFit
sunDownImageView.tintColor = ThemeManager.currentTheme.secondaryTextColor
sunActivityEndLabel.font = AppFont.SFPro.regular(size: 14)
sunActivityEndLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
sunActivityEndLabel.text = "6:23 PM"
sunActivityEndLabel.textAlignment = .right
sunActivityContainer.addSubview(sunDownImageView)
sunActivityContainer.addSubview(sunActivityEndLabel)
sunActivityEndLabel.snp.makeConstraints { (make) in
make.right.equalToSuperview().inset(20)
make.centerY.equalTo(sunActivityStartLabel)
}
sunDownImageView.snp.makeConstraints { (make) in
make.right.equalTo(sunActivityEndLabel.snp.left).inset(-3)
make.centerY.equalTo(sunUpImageView)
}
//UV levels
sunUvView.set(uvLevel: 8)
sunActivityContainer.addSubview(sunUvView)
sunUvView.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(18)
make.height.equalTo(8)
make.top.equalTo(sunUpImageView.snp.bottom).offset(20)
}
//UL label
setUV(level: 8)
sunActivityContainer.addSubview(maxUvLabel)
maxUvLabel.snp.makeConstraints { (make) in
make.top.equalTo(sunUvView.snp.bottom).offset(11)
make.centerX.equalToSuperview()
make.bottom.bottom.equalToSuperview().inset(18)
}
//Separator
sunActivityContainer.addSubview(sunUvLineView)
sunUvLineView.snp.makeConstraints { (make) in
make.left.equalTo(sunActivityStartLabel.snp.right).offset(8)
make.right.equalTo(sunDownImageView.snp.left).offset(-8)
make.height.equalTo(8)
make.centerY.equalTo(sunActivityStartLabel)
}
}
}
//
// SunUvLineView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 24.02.2021.
//
import UIKit
class SunUvLineView: UIView {
//Private
private let kLineWidth:CGFloat = 1
private let lineColor = UIColor(hex: 0x3452aa).withAlphaComponent(0.5)
private let leftCircle = CAShapeLayer()
private let rightCircle = CAShapeLayer()
private let line = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: .zero)
prepareView()
prepareLayers()
}
override func layoutSubviews() {
super.layoutSubviews()
let radius = ((bounds.height - kLineWidth) / 2).rounded(.down)
leftCircle.path = UIBezierPath(arcCenter: .init(x: radius + kLineWidth, y: bounds.height / 2),
radius: radius,
startAngle: 0,
endAngle: 2 * .pi,
clockwise: false).cgPath
rightCircle.path = UIBezierPath(arcCenter: .init(x: bounds.width - radius - kLineWidth, y: bounds.height / 2),
radius: radius,
startAngle: 0,
endAngle: 2 * .pi,
clockwise: false).cgPath
let linePath = UIBezierPath()
linePath.move(to: .init(x: (radius * 2) + kLineWidth, y: bounds.height / 2))
linePath.addLine(to: .init(x: bounds.width - (radius * 2) - kLineWidth, y: bounds.height / 2))
line.path = linePath.cgPath
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK:- Prepare
private extension SunUvLineView {
func prepareView() {
clipsToBounds = true
backgroundColor = .clear
}
func prepareLayers() {
leftCircle.lineWidth = kLineWidth
leftCircle.strokeColor = lineColor.cgColor
leftCircle.fillColor = UIColor.clear.cgColor
layer.addSublayer(leftCircle)
rightCircle.lineWidth = kLineWidth
rightCircle.strokeColor = lineColor.cgColor
rightCircle.fillColor = UIColor.clear.cgColor
layer.addSublayer(rightCircle)
line.lineWidth = kLineWidth
line.strokeColor = lineColor.cgColor
line.fillColor = UIColor.clear.cgColor
layer.addSublayer(line)
}
}
//
// SunUvView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 24.02.2021.
//
import UIKit
private enum UVLevel:Int, CaseIterable {
case low = 0
case mediuim
case high
case veryHigh
case extreme
var color:UIColor {
switch self {
case .low:
return .clear
case .mediuim:
return UIColor(hex: 0xffea75)
case .high:
return UIColor(hex: 0xffdd00)
case .veryHigh:
return UIColor(hex: 0xffb300)
case .extreme:
return UIColor(hex: 0xff2e00)
}
}
func includedToRange(level:Int) -> Bool {
switch self {
case .low:
return 0...2 ~= level || level > 2
case .mediuim:
return 3...5 ~= level || level > 5
case .high:
return 6...7 ~= level || level > 7
case .veryHigh:
return 8...10 ~= level || level > 10
case .extreme:
return level >= 11
}
}
}
class SunUvView: UIView {
//Private
private var currentUvLevel = 0
private var levelLayers = [CALayer]()
override init(frame: CGRect) {
super.init(frame: .zero)
prepareView()
prepareLevels()
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = (self.bounds.height / 2).rounded()
updateLevelsFrame()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//Private
private func updateLavelVisibility() {
//Skip low level becasue, this level it's view itself
UVLevel.allCases.forEach {
levelLayers[$0.rawValue].isHidden = !$0.includedToRange(level: currentUvLevel)
}
}
private func updateLevelsFrame() {
//Skip low level becasue, this level it's view itself
for index in 1..<levelLayers.count {
let levelLayer = levelLayers[index]
let widthCoefficient = 12 * (CGFloat(index) - 1)
let multiplier = CGFloat(index) / CGFloat(levelLayers.count)
let diff = self.bounds.width * multiplier
let targetWidth = self.bounds.width - diff - widthCoefficient
levelLayer.frame = .init(x: (bounds.width - targetWidth) / 2, y: 0, width: targetWidth, height: bounds.height)
}
}
//Public
public func set(uvLevel:Int) {
self.currentUvLevel = uvLevel
updateLavelVisibility()
}
}
//MARK:- Prepare
private extension SunUvView {
func prepareView() {
self.backgroundColor = UIColor(hex: 0xd8d8d8)
self.clipsToBounds = true
}
func prepareLevels() {
UVLevel.allCases.forEach {
let levelLayer = CALayer()
levelLayer.backgroundColor = $0.color.cgColor
self.layer.addSublayer(levelLayer)
self.levelLayers.append(levelLayer)
}
}
}
......@@ -28,14 +28,14 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
<key>SnapKit.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>3</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