Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
1
1weather
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
1weather
Commits
4782e52f
Commit
4782e52f
authored
Feb 26, 2021
by
Dmitriy Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working on additional graphic
parent
b8dd6f8e
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
158 additions
and
196 deletions
+158
-196
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
1Weather/UI/Helpers/GraphLine.swift
+45
-31
1Weather/UI/Helpers/GraphView.swift
+48
-144
1Weather/UI/View controllers/Today/Cells/CityForecastTimePeriod/CityForecastTimePeriodCell.swift
+41
-19
1Weather/UI/View controllers/Today/Cells/CityForecastTimePeriod/PeriodForecastButton.swift
+24
-2
No files found.
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
View file @
4782e52f
No preview for this file type
1Weather/UI/Helpers/GraphLine.swift
View file @
4782e52f
...
...
@@ -17,23 +17,22 @@ 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
points
=
[
CGPoint
]()
private
let
settings
:
GraphLineSettings
private
let
onGetGraphRect
:
GraphRectClosure
private
var
sections
=
[
CubicCurve
]()
//Public
let
lineShape
=
CAShapeLayer
()
private(set)
var
tintLineShape
=
CAShapeLayer
()
private(set)
var
lineDots
=
[
LineDot
]()
public
typealias
GraphRectClosure
=
()
->
CGRect
public
private(set)
var
lineShape
=
CAShapeLayer
()
public
private(set)
var
tintLineShape
=
CAShapeLayer
()
public
private(set)
var
lineDots
=
[
LineDot
]()
init
(
graphViewRect
:
CGRect
,
points
:[
CGPoint
],
settings
:
GraphLineSettings
)
{
self
.
graphViewRect
=
graphViewRect
self
.
points
=
points
self
.
tintColor
=
settings
.
tintColor
init
(
settings
:
GraphLineSettings
,
onGetGraphRect
:
@escaping
GraphRectClosure
)
{
self
.
onGetGraphRect
=
onGetGraphRect
self
.
settings
=
settings
//Line
lineShape
.
path
=
self
.
linePath
(
from
:
points
)
.
cgPath
lineShape
.
fillColor
=
UIColor
.
clear
.
cgColor
lineShape
.
strokeColor
=
settings
.
color
.
cgColor
lineShape
.
lineWidth
=
settings
.
lineWidth
...
...
@@ -53,26 +52,12 @@ struct GraphLine {
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
)
let
startPoint
=
CGPoint
(
x
:
0
,
y
:
self
.
onGetGraphRect
()
.
height
)
let
endPoint
=
CGPoint
(
x
:
self
.
onGetGraphRect
()
.
width
,
y
:
self
.
onGetGraphRect
()
.
height
)
var
pointsToAdd
=
[
CGPoint
]()
pointsToAdd
.
append
(
startPoint
)
...
...
@@ -119,9 +104,9 @@ struct GraphLine {
}
let
leftLine
=
LineSegment
(
p0
:
.
init
(
x
:
startPointX
+
kIntersectAccuracy
,
y
:
0
),
p1
:
.
init
(
x
:
startPointX
+
kIntersectAccuracy
,
y
:
self
.
graphViewRect
.
height
))
p1
:
.
init
(
x
:
startPointX
+
kIntersectAccuracy
,
y
:
self
.
onGetGraphRect
()
.
height
))
let
rightLine
=
LineSegment
(
p0
:
.
init
(
x
:
endPointX
-
kIntersectAccuracy
,
y
:
0
),
p1
:
.
init
(
x
:
endPointX
-
kIntersectAccuracy
,
y
:
self
.
graphViewRect
.
height
))
p1
:
.
init
(
x
:
endPointX
-
kIntersectAccuracy
,
y
:
self
.
onGetGraphRect
()
.
height
))
//Get all sections for the given tint and cut them
let
tintPath
=
UIBezierPath
()
...
...
@@ -131,9 +116,9 @@ struct GraphLine {
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
))
p1
:
.
init
(
x
:
maxLeftPointX
,
y
:
self
.
onGetGraphRect
()
.
height
))
let
rightBoundary
=
LineSegment
(
p0
:
.
init
(
x
:
minRightPointX
,
y
:
0
),
p1
:
.
init
(
x
:
minRightPointX
,
y
:
self
.
graphViewRect
.
height
))
p1
:
.
init
(
x
:
minRightPointX
,
y
:
self
.
onGetGraphRect
()
.
height
))
if
let
subcurve
=
getSubcurvePath
(
baseCurve
:
section
,
leftBoundary
:
leftBoundary
,
rightBoundary
:
rightBoundary
)
...
...
@@ -157,4 +142,33 @@ struct GraphLine {
guard
let
dotToTint
=
(
lineDots
.
first
{
$0
.
center
==
point
})
else
{
return
}
dotToTint
.
shape
.
strokeColor
=
ThemeManager
.
currentTheme
.
graphTintColor
.
cgColor
}
mutating
func
updateWith
(
points
:[
CGPoint
])
{
self
.
lineDots
.
forEach
{
$0
.
shape
.
removeFromSuperlayer
()
}
self
.
sections
.
removeAll
()
self
.
lineDots
.
removeAll
()
self
.
points
=
points
guard
!
self
.
points
.
isEmpty
else
{
return
}
//Add new 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
))
}
//Refresh line path
lineShape
.
path
=
self
.
linePath
(
from
:
points
)
.
cgPath
}
}
1Weather/UI/Helpers/GraphView.swift
View file @
4782e52f
...
...
@@ -10,22 +10,43 @@ import BezierKit
class
GraphView
:
UIView
{
//Private
private
let
kIntersectAccuracy
:
CGFloat
=
2
private
let
kDotRadius
:
CGFloat
=
3
private
let
graphColor
:
UIColor
private
let
graphTintColor
:
UIColor
private
let
lineShape
=
CAShapeLayer
()
private
let
tintShape
=
CAShapeLayer
()
private
var
lineDots
=
[
LineDot
]()
private
let
cubicCurveAlgorithm
=
CubicCurveAlgorithm
()
private
var
sections
=
[
CubicCurve
]()
private
let
mainLineSettings
=
GraphLineSettings
(
lineWidth
:
3
,
dotRadius
:
3
,
dotLineWidth
:
2
,
color
:
ThemeManager
.
currentTheme
.
graphColor
,
tintColor
:
ThemeManager
.
currentTheme
.
graphTintColor
)
private
let
additionalLineSettings
=
GraphLineSettings
(
lineWidth
:
2
,
dotRadius
:
2
,
dotLineWidth
:
1
/
UIScreen
.
main
.
scale
,
color
:
UIColor
(
hex
:
0xa4a4a4
)
.
withAlphaComponent
(
0.7
),
tintColor
:
UIColor
(
hex
:
0x434343
)
.
withAlphaComponent
(
0.7
))
private
lazy
var
mainLine
:
GraphLine
=
{
let
line
=
GraphLine
(
settings
:
mainLineSettings
,
onGetGraphRect
:
{
return
self
.
frame
})
return
line
}()
private
lazy
var
additionalLine
:
GraphLine
=
{
let
line
=
GraphLine
(
settings
:
additionalLineSettings
,
onGetGraphRect
:
{
return
self
.
frame
})
return
line
}()
//MARK:- View life cycle
init
(
graphColor
:
UIColor
,
tintColor
:
UIColor
)
{
self
.
graphColor
=
graphColor
self
.
graphTintColor
=
tintColor
init
()
{
super
.
init
(
frame
:
.
zero
)
self
.
isUserInteractionEnabled
=
false
//Adding lines
layer
.
insertSublayer
(
mainLine
.
lineShape
,
at
:
0
)
layer
.
insertSublayer
(
mainLine
.
tintLineShape
,
at
:
1
)
layer
.
insertSublayer
(
additionalLine
.
lineShape
,
at
:
0
)
layer
.
insertSublayer
(
additionalLine
.
tintLineShape
,
at
:
0
)
}
required
init
?(
coder
:
NSCoder
)
{
...
...
@@ -33,147 +54,30 @@ class GraphView: UIView {
}
//Public
public
func
drawGraph
(
with
points
:[
CGPoint
])
{
//Clean up
self
.
layer
.
sublayers
?
.
forEach
{
$0
.
removeFromSuperlayer
()
}
sections
.
removeAll
()
lineDots
.
removeAll
()
guard
!
points
.
isEmpty
else
{
return
}
//Add points
points
.
forEach
{
self
.
addDot
(
point
:
$0
)
public
func
drawMainGraph
(
with
points
:[
CGPoint
])
{
mainLine
.
updateWith
(
points
:
points
)
mainLine
.
lineDots
.
forEach
{
layer
.
addSublayer
(
$0
.
shape
)
}
//Add line
lineShape
.
frame
=
self
.
bounds
lineShape
.
path
=
self
.
linePath
(
from
:
points
)
.
cgPath
lineShape
.
fillColor
=
UIColor
.
clear
.
cgColor
lineShape
.
strokeColor
=
graphColor
.
cgColor
lineShape
.
lineWidth
=
3
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
layer
.
insertSublayer
(
lineShape
,
at
:
0
)
}
public
func
tintGraphFrom
(
startPointX
:
CGFloat
,
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
.
bounds
.
height
))
let
rightLine
=
LineSegment
(
p0
:
.
init
(
x
:
endPointX
-
kIntersectAccuracy
,
y
:
0
),
p1
:
.
init
(
x
:
endPointX
-
kIntersectAccuracy
,
y
:
self
.
bounds
.
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
.
bounds
.
height
))
let
rightBoundary
=
LineSegment
(
p0
:
.
init
(
x
:
minRightPointX
,
y
:
0
),
p1
:
.
init
(
x
:
minRightPointX
,
y
:
self
.
bounds
.
height
))
if
let
subcurve
=
getSubcurvePath
(
baseCurve
:
section
,
leftBoundary
:
leftBoundary
,
rightBoundary
:
rightBoundary
)
{
tintPath
.
append
(
subcurve
)
}
}
}
//Check for empty path
if
tintPath
.
isEmpty
{
return
}
tintShape
.
path
=
tintPath
.
cgPath
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
drawAdditionalGraph
(
with
points
:[
CGPoint
])
{
additionalLine
.
updateWith
(
points
:
points
)
additionalLine
.
lineDots
.
forEach
{
layer
.
addSublayer
(
$0
.
shape
)
}
}
public
func
tintDot
(
at
:
CGPoint
)
{
lineDots
.
forEach
{
$0
.
shape
.
strokeColor
=
ThemeManager
.
currentTheme
.
graphColor
.
cgColor
}
guard
let
dotToTint
=
(
lineDots
.
first
{
$0
.
center
==
at
})
else
{
return
}
dotToTint
.
shape
.
strokeColor
=
ThemeManager
.
currentTheme
.
graphTintColor
.
cgColor
public
func
tintGraphFrom
(
startPointX
:
CGFloat
,
endPointX
:
CGFloat
)
{
mainLine
.
tintLineFrom
(
startPointX
:
startPointX
,
to
:
endPointX
)
additionalLine
.
tintLineFrom
(
startPointX
:
startPointX
,
to
:
endPointX
)
}
//Private
private
func
linePath
(
from
points
:[
CGPoint
])
->
UIBezierPath
{
let
path
=
UIBezierPath
()
let
startPoint
=
CGPoint
(
x
:
0
,
y
:
self
.
frame
.
height
)
let
endPoint
=
CGPoint
(
x
:
self
.
frame
.
width
,
y
:
self
.
frame
.
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
=
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
tintMainDotAt
(
point
:
CGPoint
)
{
mainLine
.
tintDotAt
(
point
:
point
)
}
private
func
addDot
(
point
:
CGPoint
)
{
let
dotShape
=
CAShapeLayer
()
dotShape
.
path
=
UIBezierPath
(
arcCenter
:
point
,
radius
:
kDotRadius
,
startAngle
:
0
,
endAngle
:
.
pi
*
2
,
clockwise
:
true
)
.
cgPath
dotShape
.
fillColor
=
UIColor
.
white
.
cgColor
dotShape
.
strokeColor
=
self
.
graphColor
.
cgColor
dotShape
.
lineWidth
=
2
lineDots
.
append
(
.
init
(
center
:
point
,
shape
:
dotShape
))
layer
.
addSublayer
(
dotShape
)
public
func
tintAdditionalDotAt
(
point
:
CGPoint
)
{
additionalLine
.
tintDotAt
(
point
:
point
)
}
}
1Weather/UI/View controllers/Today/Cells/CityForecastTimePeriod/CityForecastTimePeriodCell.swift
View file @
4782e52f
...
...
@@ -7,22 +7,34 @@
import
UIKit
struct
DayTemp
{
let
min
:
CGFloat
let
max
:
CGFloat
}
class
CityForecastTimePeriodCell
:
UITableViewCell
{
static
let
kIdentifier
=
"cityForecastTimePeriodCell"
//Private
private
let
periodSegmentedControl
=
ForecastTimePeriodControl
(
items
:
[
"forecast.timePeriod.daily"
.
localized
(),
"forecast.timePeriod.hourly"
.
localized
()])
private
let
kMinGraphHeight
:
CGFloat
=
5
0
private
let
kMinGraphHeight
:
CGFloat
=
2
0
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
maxTempGraphPoints
=
[
CGPoint
]()
private
var
minTempGraphPoints
=
[
CGPoint
]()
private
let
graphView
=
GraphView
()
private
let
dayTemps
=
[
DayTemp
(
min
:
8
,
max
:
17
),
DayTemp
(
min
:
9
,
max
:
17
),
DayTemp
(
min
:
7
,
max
:
18
),
DayTemp
(
min
:
7
,
max
:
17
),
DayTemp
(
min
:
8
,
max
:
17
),
DayTemp
(
min
:
8
,
max
:
18
),
DayTemp
(
min
:
9
,
max
:
18
),
DayTemp
(
min
:
8
,
max
:
16
)]
private
var
graphIsDrawn
=
false
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
...
...
@@ -57,7 +69,7 @@ class CityForecastTimePeriodCell: UITableViewCell {
width
:
scrollView
.
contentSize
.
width
,
height
:
periodButton
.
graphRect
.
height
)
graphPoints
=
get
GraphPoints
()
update
GraphPoints
()
drawGraph
()
graphIsDrawn
=
true
}
...
...
@@ -71,7 +83,8 @@ class CityForecastTimePeriodCell: UITableViewCell {
return
}
self
.
graphView
.
drawGraph
(
with
:
graphPoints
)
self
.
graphView
.
drawMainGraph
(
with
:
maxTempGraphPoints
)
self
.
graphView
.
drawAdditionalGraph
(
with
:
minTempGraphPoints
)
self
.
tintGraphAt
(
button
:
selectedButton
)
print
(
"Draw graph!"
)
}
...
...
@@ -79,31 +92,39 @@ class CityForecastTimePeriodCell: UITableViewCell {
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
])
self
.
graphView
.
tintMainDotAt
(
point
:
maxTempGraphPoints
[
button
.
index
])
self
.
graphView
.
tintAdditionalDotAt
(
point
:
minTempGraphPoints
[
button
.
index
])
}
private
func
getGraphPoints
()
->
[
CGPoint
]
{
var
points
=
[
CGPoint
]()
let
maxTemp
=
CGFloat
(
tempsArray
.
max
()
??
0
)
let
minTemp
=
CGFloat
(
tempsArray
.
min
()
??
0
)
private
func
updateGraphPoints
(){
self
.
maxTempGraphPoints
.
removeAll
()
self
.
minTempGraphPoints
.
removeAll
()
for
index
in
0
..<
stackView
.
arrangedSubviews
.
count
{
let
maxTemp
=
CGFloat
(
dayTemps
.
map
{
$0
.
max
}
.
max
()
??
0
)
let
minTemp
=
CGFloat
(
dayTemps
.
map
{
$0
.
min
}
.
min
()
??
0
)
for
index
in
0
..<
dayTemps
.
count
{
guard
let
stackButton
=
stackView
.
arrangedSubviews
[
index
]
as?
PeriodForecastButton
else
{
continue
}
let
buttonRightSide
=
stackButton
.
frame
.
origin
.
x
+
stackButton
.
bounds
.
width
let
buttonCenterX
=
(
buttonRightSide
+
stackButton
.
frame
.
origin
.
x
)
/
2
let
numberOfLevels
=
maxTemp
-
minTemp
let
levelHeight
=
(
graphView
.
frame
.
height
/
numberOfLevels
)
.
rounded
(
.
down
)
var
pointLevel
=
(
maxTemp
-
CGFloat
(
tempsArray
[
index
]))
*
levelHeight
var
maxPointLevel
=
(
maxTemp
-
dayTemps
[
index
]
.
max
)
*
levelHeight
var
minPointLevel
=
(
minTemp
+
dayTemps
[
index
]
.
min
)
*
levelHeight
//Add points offset at cirle radius if needed
pointLevel
=
max
(
pointLevel
,
5
)
pointLevel
=
min
(
pointLevel
,
graphView
.
frame
.
height
-
5
)
maxPointLevel
=
max
(
maxPointLevel
,
5
)
maxPointLevel
=
min
(
maxPointLevel
,
graphView
.
frame
.
height
-
5
)
minPointLevel
=
min
(
minPointLevel
,
5
)
minPointLevel
=
max
(
minPointLevel
,
graphView
.
frame
.
height
-
5
)
points
.
append
(
.
init
(
x
:
buttonCenterX
,
y
:
pointLevel
))
maxTempGraphPoints
.
append
(
.
init
(
x
:
buttonCenterX
,
y
:
maxPointLevel
))
minTempGraphPoints
.
append
(
.
init
(
x
:
buttonCenterX
,
y
:
minPointLevel
))
}
return
points
print
(
"break"
)
}
@objc
private
func
handleConditionButton
(
button
:
PeriodForecastButton
)
{
...
...
@@ -164,8 +185,9 @@ private extension CityForecastTimePeriodCell {
make
.
edges
.
height
.
equalToSuperview
()
}
for
index
in
0
..<
12
{
for
index
in
0
..<
dayTemps
.
count
{
let
conditionButton
=
PeriodForecastButton
()
conditionButton
.
configure
(
dayTemp
:
dayTemps
[
index
])
conditionButton
.
index
=
index
conditionButton
.
addTarget
(
self
,
action
:
#selector(
handleConditionButton(button:)
)
,
for
:
.
touchUpInside
)
conditionButton
.
isSelected
=
index
==
1
...
...
1Weather/UI/View controllers/Today/Cells/CityForecastTimePeriod/PeriodForecastButton.swift
View file @
4782e52f
...
...
@@ -13,6 +13,7 @@ class PeriodForecastButton: UIControl {
private
let
forecastImageView
=
UIImageView
()
private
let
tempLabel
=
UILabel
()
private
let
indicatorImageView
=
UIImageView
()
private
let
minTempLabel
=
UILabel
()
private
let
timeLabel
=
UILabel
()
//Public
...
...
@@ -23,7 +24,7 @@ class PeriodForecastButton: UIControl {
return
.
init
(
x
:
0
,
y
:
topInset
,
width
:
self
.
bounds
.
width
,
height
:
self
.
indicatorImageView
.
frame
.
origin
.
y
-
topInset
-
kGraphInset
)
height
:
self
.
minTempLabel
.
frame
.
origin
.
y
-
topInset
-
kGraphInset
)
}
override
init
(
frame
:
CGRect
)
{
...
...
@@ -32,6 +33,7 @@ class PeriodForecastButton: UIControl {
prepareButton
()
prepareForecastImage
()
prepareTempLabel
()
prepareMinTempLabel
()
preparePeriodIndicator
()
prepareTimeLabel
()
}
...
...
@@ -45,6 +47,7 @@ class PeriodForecastButton: UIControl {
if
isSelected
{
self
.
backgroundColor
=
UIColor
.
white
self
.
tempLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
16
)
self
.
minTempLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
12
)
self
.
timeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
12
)
self
.
indicatorImageView
.
alpha
=
1.0
self
.
layer
.
shadowColor
=
UIColor
(
hex
:
0xe5e6f4
)
.
cgColor
...
...
@@ -55,6 +58,7 @@ class PeriodForecastButton: UIControl {
else
{
self
.
backgroundColor
=
UIColor
.
white
.
withAlphaComponent
(
0.5
)
self
.
tempLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
16
)
self
.
minTempLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
12
)
self
.
timeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
12
)
self
.
indicatorImageView
.
alpha
=
0.5
self
.
layer
.
shadowColor
=
UIColor
.
clear
.
cgColor
...
...
@@ -64,6 +68,12 @@ class PeriodForecastButton: UIControl {
}
}
}
//Public
public
func
configure
(
dayTemp
:
DayTemp
)
{
self
.
tempLabel
.
text
=
"
\(
Int
(
dayTemp
.
max
)
)
°"
self
.
minTempLabel
.
text
=
"
\(
Int
(
dayTemp
.
min
)
)
°"
}
}
private
extension
PeriodForecastButton
{
...
...
@@ -101,6 +111,18 @@ private extension PeriodForecastButton {
}
}
func
prepareMinTempLabel
()
{
minTempLabel
.
isUserInteractionEnabled
=
false
minTempLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
12
)
minTempLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
addSubview
(
minTempLabel
)
minTempLabel
.
snp
.
makeConstraints
{
(
make
)
in
make
.
centerX
.
equalToSuperview
()
make
.
top
.
greaterThanOrEqualTo
(
tempLabel
.
snp
.
bottom
)
.
offset
(
55
)
}
}
func
preparePeriodIndicator
()
{
indicatorImageView
.
isUserInteractionEnabled
=
false
indicatorImageView
.
contentMode
=
.
scaleAspectFit
...
...
@@ -110,7 +132,7 @@ private extension PeriodForecastButton {
indicatorImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
width
.
height
.
equalTo
(
12
)
make
.
centerX
.
equalToSuperview
()
make
.
top
.
greaterThanOrEqualTo
(
tempLabel
.
snp
.
bottom
)
.
offset
(
10
0
)
make
.
top
.
equalTo
(
minTempLabel
.
snp
.
bottom
)
.
offset
(
1
0
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment