Commit 73bc486a by Dmitriy Stepanets

- Added graph drawning logic

- Working on sun ellipse path
parent 18d0db43
......@@ -20,6 +20,7 @@ class GraphView: UIView {
private let graphColor:UIColor
private let graphTintColor:UIColor
private let lineShape = CAShapeLayer()
private let tintShape = CAShapeLayer()
private var lineDots = [GraphDot]()
private let cubicCurveAlgorithm = CubicCurveAlgorithm()
private var sections = [CubicCurve]()
......@@ -115,14 +116,15 @@ class GraphView: UIView {
//Check for empty path
if tintPath.isEmpty { return }
let tintShape = CAShapeLayer()
tintShape.path = tintPath.cgPath
tintShape.fillColor = UIColor.clear.cgColor
tintShape.strokeColor = ThemeManager.currentTheme.graphTintColor.cgColor
tintShape.lineWidth = 3
tintShape.lineCap = .round
tintShape.lineJoin = .round
layer.insertSublayer(tintShape, at: 1)
if tintShape.superlayer == nil {
tintShape.fillColor = UIColor.clear.cgColor
tintShape.strokeColor = ThemeManager.currentTheme.graphTintColor.cgColor
tintShape.lineWidth = 3
tintShape.lineCap = .round
tintShape.lineJoin = .round
layer.insertSublayer(tintShape, at: 1)
}
}
public func tintDot(at: CGPoint) {
......
......@@ -14,14 +14,17 @@ class CityForecastTimePeriodCell: UITableViewCell {
private let periodSegmentedControl = ForecastTimePeriodControl(items: ["forecast.timePeriod.daily".localized(),
"forecast.timePeriod.hourly".localized(),
"forecast.timePeriod.minutely".localized()])
private let kMinGraphHeight:CGFloat = 50
private let scrollView = UIScrollView()
private let stackView = UIStackView()
private let summaryView = UIView()
private let summaryImageView = UIImageView()
private let summaryLabel = UILabel()
private var graphPoints = [CGPoint]()
private let graphView = GraphView(graphColor: ThemeManager.currentTheme.graphColor,
tintColor: ThemeManager.currentTheme.graphTintColor)
private let tempsArray = [20,18,25,24,22,20,23,25,27,26,23,20]
private var graphIsDrawn = false
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
......@@ -38,28 +41,46 @@ class CityForecastTimePeriodCell: UITableViewCell {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
//Public
public func drawGraphIfNeeded() {
guard !graphIsDrawn else { return }
//Checking for correct height
guard
let periodButton = stackView.arrangedSubviews.first as? PeriodForecastButton,
periodButton.graphRect.height >= kMinGraphHeight
else {
return
}
graphView.frame = .init(x: 0,
y: periodButton.graphRect.origin.y,
width: scrollView.contentSize.width,
height: periodButton.graphRect.height)
graphPoints = getGraphPoints()
drawGraph()
graphIsDrawn = true
}
//Private
private func drawGraph() {
guard let periodButtons = stackView.arrangedSubviews as? [PeriodForecastButton] else { return }
for (index, button) in periodButtons.enumerated() {
if button.isSelected {
let graphRect = button.getGraphRect()
guard graphRect.width > 0 else { return }
graphView.frame = .init(x: 0, y: graphRect.origin.y, width: scrollView.contentSize.width, height: graphRect.height)
//Draw points and lines
let graphPoints = self.getGraphPoints()
self.graphView.drawGraph(with: graphPoints)
self.graphView.tintGraphFrom(startPointX: button.frame.origin.x,
endPointX: button.frame.origin.x + button.bounds.width)
self.graphView.tintDot(at: graphPoints[index])
return
}
guard
let periodButtons = stackView.arrangedSubviews as? [PeriodForecastButton],
let selectedButton = (periodButtons.first{ $0.isSelected })
else {
return
}
self.graphView.drawGraph(with: graphPoints)
self.tintGraphAt(button: selectedButton)
print("Draw graph!")
}
private func tintGraphAt(button:PeriodForecastButton) {
self.graphView.tintGraphFrom(startPointX: button.frame.origin.x,
endPointX: button.frame.origin.x + button.bounds.width)
self.graphView.tintDot(at: graphPoints[button.index])
}
private func getGraphPoints() -> [CGPoint] {
......@@ -90,9 +111,12 @@ class CityForecastTimePeriodCell: UITableViewCell {
stackView.arrangedSubviews.forEach {
if let periodButton = $0 as? PeriodForecastButton {
periodButton.isSelected = periodButton === button
if periodButton.isSelected {
tintGraphAt(button: periodButton)
}
}
}
drawGraph()
}
}
......@@ -143,6 +167,7 @@ private extension CityForecastTimePeriodCell {
for index in 0..<12 {
let conditionButton = PeriodForecastButton()
conditionButton.index = index
conditionButton.addTarget(self, action: #selector(handleConditionButton(button:)), for: .touchUpInside)
conditionButton.isSelected = index == 1
stackView.addArrangedSubview(conditionButton)
......
......@@ -14,6 +14,17 @@ class PeriodForecastButton: UIControl {
private let tempLabel = UILabel()
private let indicatorImageView = UIImageView()
private let timeLabel = UILabel()
//Public
var index:Int = -1
var graphRect:CGRect {
let topInset = self.tempLabel.frame.origin.y + self.tempLabel.frame.size.height + kGraphInset
return .init(x: 0,
y: topInset,
width: self.bounds.width,
height: self.indicatorImageView.frame.origin.y - topInset - kGraphInset)
}
override init(frame: CGRect) {
super.init(frame: .zero)
......@@ -53,16 +64,6 @@ class PeriodForecastButton: UIControl {
}
}
}
//Public
public func getGraphRect() -> CGRect {
let topInset = self.tempLabel.frame.origin.y + self.tempLabel.frame.size.height + kGraphInset
return .init(x: 0,
y: topInset,
width: self.bounds.width,
height: self.indicatorImageView.frame.origin.y - topInset - kGraphInset)
}
}
private extension PeriodForecastButton {
......
......@@ -22,6 +22,25 @@ class CitySunCell: UITableViewCell {
private let sunActivityStartLabel = UILabel()
private let sunActivityEndLabel = UILabel()
private let maxUvLabel = UILabel()
private var dashLinePoints:[CGPoint] {
let earthImageViewInset:CGFloat = 16
let sideInset:CGFloat = 18
let topInset = earthImageView.frame.origin.y - earthImageViewInset
let a: CGFloat = (infographicContainer.frame.width / 2) - sideInset
let b: CGFloat = earthImageView.frame.height + earthImageViewInset
var points = [CGPoint]()
let tValues = stride(from: -.pi, to: 0, by: 0.02).map{$0}
for t in tValues{
let x = a * cos(CGFloat(t)) + a + sideInset
let y = b * sin(CGFloat(t)) + b + topInset
points.append(CGPoint(x: x, y: y))
}
return points
}
//Computed
private var dashLinePath:CGPath?
......@@ -47,23 +66,18 @@ class CitySunCell: UITableViewCell {
}
private func drawDashLine() {
let dashHeight = earthImageView.bounds.height + 32
let dashLineRect = CGRect(x: 30,
y: earthImageView.frame.origin.y - 16,
width: infographicContainer.frame.width - 60,
height: dashHeight * 2)
dashLinePath = UIBezierPath(ovalIn: dashLineRect).cgPath
//Mask
let maskLayer = CAShapeLayer()
let maskPath = UIBezierPath(rect: CGRect(x: dashLineRect.origin.x, y: dashLineRect.origin.y,
width: dashLineRect.width, height: dashLineRect.height / 2 - 16))
maskLayer.path = maskPath.cgPath
maskLayer.fillRule = .evenOdd
infographicDashLine.path = dashLinePath
infographicDashLine.mask = maskLayer
let dashPath = UIBezierPath()
for index in 0..<dashLinePoints.count {
if index == 0 {
dashPath.move(to: dashLinePoints[index])
continue
}
dashPath.addLine(to: dashLinePoints[index])
}
infographicDashLine.path = dashPath.cgPath
}
private func updateSunPosition() {
......@@ -141,11 +155,13 @@ private extension CitySunCell {
//Earth
earthImageView.contentMode = .scaleAspectFit
earthImageView.clipsToBounds = true
infographicContainer.addSubview(earthImageView)
earthImageView.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(18)
make.bottom.equalToSuperview()
make.height.greaterThanOrEqualTo(100).priority(.low)
}
//Dash line
......@@ -165,6 +181,7 @@ private extension CitySunCell {
}
func prepareSunActivityContainer() {
sunActivityContainer.isHidden = true
sunActivityContainer.clipsToBounds = false
sunActivityContainer.backgroundColor = .white
sunActivityContainer.layer.cornerRadius = 12
......
......@@ -124,5 +124,13 @@ extension TodayViewController: UITableViewDataSource {
//MARK:- UITableView Delegate
extension TodayViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let timePeriodCell = cell as? CityForecastTimePeriodCell {
timePeriodCell.drawGraphIfNeeded()
}
if let sunCell = cell as? CitySunCell {
}
}
}
import Foundation
import UIKit
let a: CGFloat = 169.5
let b: CGFloat = 100
var points = [CGPoint]()
let tValues = stride(from: -0, to: .pi, by: 0.1).map{$0}
for t in tValues {
let x = a * cos(CGFloat(t)) + a
let y = b * sin(CGFloat(t))
points.append(CGPoint(x: x, y: y))
}
print(points)
let path = UIBezierPath()
for index in 0..<points.count {
if index == 0 {
path.move(to: points[index])
continue
}
path.addLine(to: points[index])
}
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