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
27d0bb5a
Commit
27d0bb5a
authored
Mar 05, 2021
by
Dmitriy Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished today cells mapping
parent
5d1529f8
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
209 additions
and
85 deletions
+209
-85
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
1Weather/AppDelegate.swift
+0
-3
1Weather/Model/HelperTypes.swift
+23
-1
1Weather/Model/LocationManager.swift
+22
-7
1Weather/UI/Buttons/NavigationCityButton.swift
+24
-2
1Weather/UI/View controllers/Today/Cells/CityForecastCell.swift
+0
-3
1Weather/UI/View controllers/Today/Cells/CityMoonCell/CityMoonCell.swift
+62
-29
1Weather/UI/View controllers/Today/Cells/CitySunCell/CitySunCell.swift
+68
-39
1Weather/UI/View controllers/Today/Cells/TodayCellFactory.swift
+2
-0
1Weather/UI/View controllers/Today/TodayViewController.swift
+5
-1
1Weather/ViewModels/TodayViewModel.swift
+3
-0
No files found.
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
View file @
27d0bb5a
No preview for this file type
1Weather/AppDelegate.swift
View file @
27d0bb5a
...
@@ -13,11 +13,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
...
@@ -13,11 +13,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var
window
:
UIWindow
?
var
window
:
UIWindow
?
func
application
(
_
application
:
UIApplication
,
didFinishLaunchingWithOptions
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?)
->
Bool
{
func
application
(
_
application
:
UIApplication
,
didFinishLaunchingWithOptions
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?)
->
Bool
{
ThemeManager
.
refreshAppearance
()
ThemeManager
.
refreshAppearance
()
LocationManager
.
shared
.
currentLocation
=
Location
(
coordinates
:
CLLocationCoordinate2D
(
latitude
:
40.730610
,
longitude
:
-
73.935242
),
timeZone
:
TimeZone
(
identifier
:
"EST"
)
!
)
self
.
window
=
UIWindow
(
frame
:
UIScreen
.
main
.
bounds
)
self
.
window
=
UIWindow
(
frame
:
UIScreen
.
main
.
bounds
)
let
appCoordinator
=
AppCoordinator
(
window
:
self
.
window
!
)
let
appCoordinator
=
AppCoordinator
(
window
:
self
.
window
!
)
appCoordinator
.
start
()
appCoordinator
.
start
()
...
...
1Weather/Model/HelperTypes.swift
View file @
27d0bb5a
...
@@ -7,7 +7,6 @@
...
@@ -7,7 +7,6 @@
import
Foundation
import
Foundation
public
enum
WeatherType
:
String
,
CaseIterable
{
public
enum
WeatherType
:
String
,
CaseIterable
{
case
clearDay
=
"clearDay"
case
clearDay
=
"clearDay"
case
partlyCloudyDay
=
"partlyCloudyDay"
case
partlyCloudyDay
=
"partlyCloudyDay"
...
@@ -149,6 +148,29 @@ public enum MoonPhase: String, Codable {
...
@@ -149,6 +148,29 @@ public enum MoonPhase: String, Codable {
case
lastQuarterMoon
=
"Last Quarter Moon"
case
lastQuarterMoon
=
"Last Quarter Moon"
case
waningCrescentMoon
=
"Waning Crescent Moon"
case
waningCrescentMoon
=
"Waning Crescent Moon"
case
unknown
=
""
case
unknown
=
""
var
localized
:
String
{
switch
self
{
case
.
newMoon
:
return
"moon.phase.new"
.
localized
()
case
.
waxingCrescentMoon
:
return
"moon.phase.waxingCrescent"
.
localized
()
case
.
quarterMoon
:
return
"moon.phase.firstQuarter"
.
localized
()
case
.
waxingGibbousMoon
:
return
"moon.phase.waxingGibbous"
.
localized
()
case
.
fullMoon
:
return
"moon.phase.fullMoon"
.
localized
()
case
.
waningGibbousMoon
:
return
"moon.phase.waningGibbous"
.
localized
()
case
.
lastQuarterMoon
:
return
"moon.phase.thirdQuarter"
.
localized
()
case
.
waningCrescentMoon
:
return
"moon.phase.wanningCrescent"
.
localized
()
case
.
unknown
:
return
"unknown"
}
}
}
}
public
struct
Time
:
CustomStringConvertible
,
Codable
{
public
struct
Time
:
CustomStringConvertible
,
Codable
{
...
...
1Weather/Model/LocationManager.swift
View file @
27d0bb5a
...
@@ -15,6 +15,20 @@ public class LocationManager {
...
@@ -15,6 +15,20 @@ public class LocationManager {
private
let
log
=
Logger
(
componentName
:
"LocationManager"
)
private
let
log
=
Logger
(
componentName
:
"LocationManager"
)
private
let
delegates
=
MulticastDelegate
<
LocationManagerDelegate
>
()
private
let
delegates
=
MulticastDelegate
<
LocationManagerDelegate
>
()
private
let
weatherUpdateSource
:
WeatherSource
private
let
weatherUpdateSource
:
WeatherSource
private
let
defaultLocation
=
Location
(
coordinates
:
.
init
(
latitude
:
37.3230
,
longitude
:
-
122.0322
),
timeZone
:
TimeZone
(
abbreviation
:
"PST"
)
!
)
private
var
_currentLocation
:
Location
?
{
didSet
{
if
oldValue
?
.
description
!=
currentLocation
?
.
description
{
log
.
info
(
"Current location changed to:
\(
currentLocation
?
.
description
??
"nil"
)
"
)
}
log
.
info
(
"Location updated."
)
delegates
.
invoke
{
[
weak
self
]
(
delegate
)
in
guard
let
self
=
self
else
{
return
}
delegate
.
locationManager
(
self
,
changedCurrentLocation
:
currentLocation
)
}
}
}
public
static
let
shared
=
LocationManager
(
weatherUpdateSource
:
WdtWeatherSource
())
public
static
let
shared
=
LocationManager
(
weatherUpdateSource
:
WdtWeatherSource
())
...
@@ -23,15 +37,16 @@ public class LocationManager {
...
@@ -23,15 +37,16 @@ public class LocationManager {
}
}
public
var
currentLocation
:
Location
?
{
public
var
currentLocation
:
Location
?
{
didS
et
{
g
et
{
if
oldValue
?
.
description
!=
currentLocation
?
.
description
{
guard
let
location
=
_currentLocation
else
{
log
.
info
(
"Current location changed to:
\(
currentLocation
?
.
description
??
"nil"
)
"
)
return
defaultLocation
}
}
log
.
info
(
"Location updated."
)
delegates
.
invoke
{
[
weak
self
]
(
delegate
)
in
return
location
guard
let
self
=
self
else
{
return
}
delegate
.
locationManager
(
self
,
changedCurrentLocation
:
currentLocation
)
}
}
set
{
_currentLocation
=
newValue
}
}
}
}
...
...
1Weather/UI/Buttons/NavigationCityButton.swift
View file @
27d0bb5a
...
@@ -15,6 +15,12 @@ class NavigationCityButton: UIControl {
...
@@ -15,6 +15,12 @@ class NavigationCityButton: UIControl {
private
let
downArrowImageView
=
UIImageView
()
private
let
downArrowImageView
=
UIImageView
()
private
let
timeLabel
=
UILabel
()
private
let
timeLabel
=
UILabel
()
private
let
kSpaceForDownArrow
:
CGFloat
=
10
private
let
kSpaceForDownArrow
:
CGFloat
=
10
private
static
let
timeFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"h:mm a"
return
fmt
}()
init
()
{
init
()
{
super
.
init
(
frame
:
.
zero
)
super
.
init
(
frame
:
.
zero
)
...
@@ -49,8 +55,26 @@ class NavigationCityButton: UIControl {
...
@@ -49,8 +55,26 @@ class NavigationCityButton: UIControl {
cityLabel
.
textColor
=
normalColor
cityLabel
.
textColor
=
normalColor
timeLabel
.
textColor
=
normalColor
timeLabel
.
textColor
=
normalColor
}
}
public
func
configure
(
with
location
:
Location
?)
{
guard
let
loc
=
location
else
{
self
.
cityLabel
.
text
=
"N/A"
self
.
timeLabel
.
text
=
nil
return
}
self
.
cityLabel
.
text
=
loc
.
cityName
if
let
today
=
loc
.
today
?
.
date
{
NavigationCityButton
.
timeFormatter
.
timeZone
=
loc
.
timeZone
self
.
timeLabel
.
text
=
NavigationCityButton
.
timeFormatter
.
string
(
from
:
today
)
}
else
{
self
.
timeLabel
.
text
=
nil
}
}
}
}
//MARK:- Prepare
private
extension
NavigationCityButton
{
private
extension
NavigationCityButton
{
func
prepareContentView
()
{
func
prepareContentView
()
{
contentView
.
isUserInteractionEnabled
=
false
contentView
.
isUserInteractionEnabled
=
false
...
@@ -67,7 +91,6 @@ private extension NavigationCityButton {
...
@@ -67,7 +91,6 @@ private extension NavigationCityButton {
cityLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
16
)
cityLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
16
)
cityLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
cityLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
cityLabel
.
textAlignment
=
.
left
cityLabel
.
textAlignment
=
.
left
cityLabel
.
text
=
"New York"
contentView
.
addSubview
(
cityLabel
)
contentView
.
addSubview
(
cityLabel
)
cityLabel
.
snp
.
makeConstraints
{
(
make
)
in
cityLabel
.
snp
.
makeConstraints
{
(
make
)
in
...
@@ -109,7 +132,6 @@ private extension NavigationCityButton {
...
@@ -109,7 +132,6 @@ private extension NavigationCityButton {
timeLabel
.
isUserInteractionEnabled
=
false
timeLabel
.
isUserInteractionEnabled
=
false
timeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
timeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
timeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
timeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
timeLabel
.
text
=
"9:41 AM"
timeLabel
.
sizeToFit
()
timeLabel
.
sizeToFit
()
contentView
.
addSubview
(
timeLabel
)
contentView
.
addSubview
(
timeLabel
)
...
...
1Weather/UI/View controllers/Today/Cells/CityForecastCell.swift
View file @
27d0bb5a
...
@@ -83,7 +83,6 @@ private extension CityForecastCell {
...
@@ -83,7 +83,6 @@ private extension CityForecastCell {
func
prepareTemperatureLabel
()
{
func
prepareTemperatureLabel
()
{
temperatureLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
75
)
temperatureLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
75
)
temperatureLabel
.
text
=
"96°"
temperatureLabel
.
textAlignment
=
.
left
temperatureLabel
.
textAlignment
=
.
left
temperatureLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
temperatureLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
temperatureLabel
.
setContentHuggingPriority
(
.
fittingSizeLevel
,
for
:
.
vertical
)
temperatureLabel
.
setContentHuggingPriority
(
.
fittingSizeLevel
,
for
:
.
vertical
)
...
@@ -98,7 +97,6 @@ private extension CityForecastCell {
...
@@ -98,7 +97,6 @@ private extension CityForecastCell {
func
prepareForecastLabel
()
{
func
prepareForecastLabel
()
{
forecastDescriptionLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
16
)
forecastDescriptionLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
16
)
forecastDescriptionLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
forecastDescriptionLabel
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
forecastDescriptionLabel
.
text
=
"
\(
"forecast.partyCloudy"
.
localized
()
)
| 97°/89°"
container
.
addSubview
(
forecastDescriptionLabel
)
container
.
addSubview
(
forecastDescriptionLabel
)
forecastDescriptionLabel
.
snp
.
makeConstraints
{
(
make
)
in
forecastDescriptionLabel
.
snp
.
makeConstraints
{
(
make
)
in
...
@@ -110,7 +108,6 @@ private extension CityForecastCell {
...
@@ -110,7 +108,6 @@ private extension CityForecastCell {
func
prepareFeelsLikeLabel
()
{
func
prepareFeelsLikeLabel
()
{
feelsLikeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
12
)
feelsLikeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
12
)
feelsLikeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
feelsLikeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
feelsLikeLabel
.
text
=
"Feels like 103° - Due to high humidity"
container
.
addSubview
(
feelsLikeLabel
)
container
.
addSubview
(
feelsLikeLabel
)
feelsLikeLabel
.
snp
.
makeConstraints
{
(
make
)
in
feelsLikeLabel
.
snp
.
makeConstraints
{
(
make
)
in
...
...
1Weather/UI/View controllers/Today/Cells/CityMoonCell/CityMoonCell.swift
View file @
27d0bb5a
...
@@ -15,14 +15,27 @@ class CityMoonCell: UITableViewCell {
...
@@ -15,14 +15,27 @@ class CityMoonCell: UITableViewCell {
private
let
container
=
UIView
()
private
let
container
=
UIView
()
private
let
infoLabel
=
UILabel
()
private
let
infoLabel
=
UILabel
()
private
let
baseLine
=
UIView
()
private
let
baseLine
=
UIView
()
private
let
moon
Up
ImageView
=
UIImageView
()
private
let
moon
rise
ImageView
=
UIImageView
()
private
let
moon
Up
TimeLabel
=
UILabel
()
private
let
moon
rise
TimeLabel
=
UILabel
()
private
let
moon
Down
ImageView
=
UIImageView
()
private
let
moon
set
ImageView
=
UIImageView
()
private
let
moon
Down
TimeLabel
=
UILabel
()
private
let
moon
set
TimeLabel
=
UILabel
()
private
let
circleGradientLayer
=
CAGradientLayer
()
private
let
circleGradientLayer
=
CAGradientLayer
()
private
let
moonImageView
=
UIImageView
()
private
let
moonImageView
=
UIImageView
()
private
let
moonTypeImageView
=
UIImageView
()
private
let
moonTypeImageView
=
UIImageView
()
private
let
moonTypeLabel
=
UILabel
()
private
let
moonTypeLabel
=
UILabel
()
private
var
moonProgress
:
CGFloat
=
0.0
//Computed
private
static
let
dateFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"h:mm a"
return
fmt
}()
private
static
let
nowDateFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"yyyy-MM-dd h:mm a"
return
fmt
}()
//MARK:- Cell life cycle
//MARK:- Cell life cycle
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
...
@@ -74,8 +87,8 @@ class CityMoonCell: UITableViewCell {
...
@@ -74,8 +87,8 @@ class CityMoonCell: UITableViewCell {
}
}
private
func
moonPath
(
progress
:
CGFloat
)
->
UIBezierPath
{
private
func
moonPath
(
progress
:
CGFloat
)
->
UIBezierPath
{
var
pathProgress
=
max
(
0
,
progress
)
var
pathProgress
=
max
(
0
.04
,
progress
)
pathProgress
=
min
(
1
,
pathProgress
)
pathProgress
=
min
(
0.96
,
pathProgress
)
let
start
:
CGFloat
=
-.
pi
let
start
:
CGFloat
=
-.
pi
let
end
:
CGFloat
=
0
let
end
:
CGFloat
=
0
...
@@ -92,13 +105,35 @@ class CityMoonCell: UITableViewCell {
...
@@ -92,13 +105,35 @@ class CityMoonCell: UITableViewCell {
}
}
//Public
//Public
public
func
configure
(
with
location
:
Location
)
{
CityMoonCell
.
dateFormatter
.
timeZone
=
location
.
today
?
.
timeZone
CityMoonCell
.
nowDateFormatter
.
timeZone
=
location
.
today
?
.
timeZone
moonTypeLabel
.
text
=
location
.
today
?
.
moonPhase
?
.
localized
guard
let
moonrise
=
location
.
today
?
.
moonrise
,
let
moonset
=
location
.
today
?
.
moonset
else
{
return
}
moonriseTimeLabel
.
text
=
CityMoonCell
.
dateFormatter
.
string
(
from
:
moonrise
)
moonsetTimeLabel
.
text
=
CityMoonCell
.
dateFormatter
.
string
(
from
:
moonset
)
let
moonTimePeriod
=
moonset
.
timeIntervalSince1970
-
moonrise
.
timeIntervalSince1970
let
nowString
=
CityMoonCell
.
nowDateFormatter
.
string
(
from
:
Date
())
let
nowDate
=
CityMoonCell
.
nowDateFormatter
.
date
(
from
:
nowString
)
??
Date
()
self
.
moonProgress
=
CGFloat
((
nowDate
.
timeIntervalSince1970
-
moonrise
.
timeIntervalSince1970
)
/
moonTimePeriod
)
}
public
func
updateMoonPosition
()
{
public
func
updateMoonPosition
()
{
contentView
.
layoutIfNeeded
()
moonImageView
.
layer
.
removeAnimation
(
forKey
:
"moon.position"
)
moonImageView
.
layer
.
removeAnimation
(
forKey
:
"moon.position"
)
moonImageView
.
frame
.
origin
=
.
init
(
x
:
kCircleInset
-
moonImageView
.
frame
.
width
/
2
,
moonImageView
.
frame
.
origin
=
.
init
(
x
:
kCircleInset
-
moonImageView
.
frame
.
width
/
2
,
y
:
baseLine
.
frame
.
origin
.
y
-
moonImageView
.
frame
.
height
)
y
:
baseLine
.
frame
.
origin
.
y
-
moonImageView
.
frame
.
height
)
let
animation
=
CAKeyframeAnimation
(
keyPath
:
"position"
)
let
animation
=
CAKeyframeAnimation
(
keyPath
:
"position"
)
animation
.
path
=
self
.
moonPath
(
progress
:
0.7
)
.
cgPath
animation
.
path
=
self
.
moonPath
(
progress
:
moonProgress
)
.
cgPath
animation
.
calculationMode
=
.
paced
animation
.
calculationMode
=
.
paced
animation
.
duration
=
1.3
animation
.
duration
=
1.3
animation
.
rotationMode
=
.
rotateAuto
animation
.
rotationMode
=
.
rotateAuto
...
@@ -177,23 +212,23 @@ private extension CityMoonCell {
...
@@ -177,23 +212,23 @@ private extension CityMoonCell {
}
}
//Up arrow
//Up arrow
moon
Up
ImageView
.
contentMode
=
.
scaleAspectFit
moon
rise
ImageView
.
contentMode
=
.
scaleAspectFit
moon
Up
ImageView
.
image
=
UIImage
(
named
:
"moon_up_arrow"
)
moon
rise
ImageView
.
image
=
UIImage
(
named
:
"moon_up_arrow"
)
moon
Up
ImageView
.
tintColor
=
UIColor
(
hex
:
0x1f67f3
)
moon
rise
ImageView
.
tintColor
=
UIColor
(
hex
:
0x1f67f3
)
container
.
addSubview
(
moon
Up
ImageView
)
container
.
addSubview
(
moon
rise
ImageView
)
moon
Up
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
moon
rise
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalToSuperview
()
.
inset
(
22
)
make
.
left
.
equalToSuperview
()
.
inset
(
22
)
make
.
bottom
.
equalTo
(
baseLine
.
snp
.
top
)
.
offset
(
-
20
)
make
.
bottom
.
equalTo
(
baseLine
.
snp
.
top
)
.
offset
(
-
20
)
}
}
//Down arrow
//Down arrow
moon
Down
ImageView
.
contentMode
=
.
scaleAspectFit
moon
set
ImageView
.
contentMode
=
.
scaleAspectFit
moon
Down
ImageView
.
image
=
UIImage
(
named
:
"moon_down_arrow"
)
moon
set
ImageView
.
image
=
UIImage
(
named
:
"moon_down_arrow"
)
moon
Down
ImageView
.
tintColor
=
UIColor
(
hex
:
0x1f67f3
)
moon
set
ImageView
.
tintColor
=
UIColor
(
hex
:
0x1f67f3
)
container
.
addSubview
(
moon
Down
ImageView
)
container
.
addSubview
(
moon
set
ImageView
)
moon
Down
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
moon
set
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
right
.
equalToSuperview
()
.
inset
(
22
)
make
.
right
.
equalToSuperview
()
.
inset
(
22
)
make
.
bottom
.
equalTo
(
baseLine
.
snp
.
top
)
.
offset
(
-
20
)
make
.
bottom
.
equalTo
(
baseLine
.
snp
.
top
)
.
offset
(
-
20
)
}
}
...
@@ -220,24 +255,22 @@ private extension CityMoonCell {
...
@@ -220,24 +255,22 @@ private extension CityMoonCell {
}
}
//Times
//Times
moonUpTimeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
14
)
moonriseTimeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
14
)
moonUpTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
moonriseTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
moonUpTimeLabel
.
text
=
"6:11 AM"
moonriseTimeLabel
.
textAlignment
=
.
left
moonUpTimeLabel
.
textAlignment
=
.
left
container
.
addSubview
(
moonriseTimeLabel
)
container
.
addSubview
(
moonUpTimeLabel
)
moon
Up
TimeLabel
.
snp
.
makeConstraints
{
(
make
)
in
moon
rise
TimeLabel
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalToSuperview
()
.
inset
(
20
)
make
.
left
.
equalToSuperview
()
.
inset
(
20
)
make
.
top
.
equalTo
(
baseLine
.
snp
.
bottom
)
.
offset
(
18
)
make
.
top
.
equalTo
(
baseLine
.
snp
.
bottom
)
.
offset
(
18
)
}
}
moonDownTimeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
14
)
moonsetTimeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
14
)
moonDownTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
moonsetTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
moonDownTimeLabel
.
text
=
"5:47 PM"
moonsetTimeLabel
.
textAlignment
=
.
right
moonDownTimeLabel
.
textAlignment
=
.
right
container
.
addSubview
(
moonsetTimeLabel
)
container
.
addSubview
(
moonDownTimeLabel
)
moon
Down
TimeLabel
.
snp
.
makeConstraints
{
(
make
)
in
moon
set
TimeLabel
.
snp
.
makeConstraints
{
(
make
)
in
make
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
top
.
equalTo
(
baseLine
.
snp
.
bottom
)
.
offset
(
18
)
make
.
top
.
equalTo
(
baseLine
.
snp
.
bottom
)
.
offset
(
18
)
}
}
...
...
1Weather/UI/View controllers/Today/Cells/CitySunCell/CitySunCell.swift
View file @
27d0bb5a
...
@@ -42,13 +42,24 @@ class CitySunCell: UITableViewCell {
...
@@ -42,13 +42,24 @@ class CitySunCell: UITableViewCell {
//Sun
//Sun
private
let
sunImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun"
))
private
let
sunImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun"
))
private
let
sunActivityContainer
=
UIView
()
private
let
sunActivityContainer
=
UIView
()
private
let
sun
ActivityStart
Label
=
UILabel
()
private
let
sun
riseTime
Label
=
UILabel
()
private
let
sun
ActivityEnd
Label
=
UILabel
()
private
let
sun
setTime
Label
=
UILabel
()
private
let
sunUvLineView
=
SunUvLineView
()
private
let
sunUvLineView
=
SunUvLineView
()
private
let
sunUvView
=
SunUvView
()
private
let
sunUvView
=
SunUvView
()
private
let
maxUvLabel
=
UILabel
()
private
let
maxUvLabel
=
UILabel
()
private
var
sunProgress
:
CGFloat
=
0.0
//Computed
//Computed
private
static
let
dateFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"h:mm a"
return
fmt
}()
private
static
let
nowDateFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"yyyy-MM-dd h:mm a"
return
fmt
}()
private
var
earthCircleSegment
:
CircleSegment
{
private
var
earthCircleSegment
:
CircleSegment
{
return
.
init
(
chord
:
earthImageView
.
frame
.
width
,
return
.
init
(
chord
:
earthImageView
.
frame
.
width
,
height
:
earthImageView
.
frame
.
height
)
height
:
earthImageView
.
frame
.
height
)
...
@@ -76,6 +87,24 @@ class CitySunCell: UITableViewCell {
...
@@ -76,6 +87,24 @@ class CitySunCell: UITableViewCell {
drawDashLine
()
drawDashLine
()
}
}
public
func
configure
(
with
location
:
Location
)
{
guard
let
sunrise
=
location
.
today
?
.
sunrise
,
let
sunset
=
location
.
today
?
.
sunset
else
{
return
}
CitySunCell
.
dateFormatter
.
timeZone
=
location
.
today
?
.
timeZone
CitySunCell
.
nowDateFormatter
.
timeZone
=
location
.
today
?
.
timeZone
sunriseTimeLabel
.
text
=
CitySunCell
.
dateFormatter
.
string
(
from
:
sunrise
)
sunsetTimeLabel
.
text
=
CitySunCell
.
dateFormatter
.
string
(
from
:
sunset
)
let
sunTimePeriod
=
sunset
.
timeIntervalSince1970
-
sunrise
.
timeIntervalSince1970
let
nowString
=
CitySunCell
.
nowDateFormatter
.
string
(
from
:
Date
())
let
nowDate
=
CitySunCell
.
nowDateFormatter
.
date
(
from
:
nowString
)
??
Date
()
self
.
sunProgress
=
CGFloat
((
nowDate
.
timeIntervalSince1970
-
sunset
.
timeIntervalSince1970
)
/
sunTimePeriod
)
}
required
init
?(
coder
:
NSCoder
)
{
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
fatalError
(
"init(coder:) has not been implemented"
)
}
}
...
@@ -85,8 +114,8 @@ class CitySunCell: UITableViewCell {
...
@@ -85,8 +114,8 @@ class CitySunCell: UITableViewCell {
}
}
private
func
dashLinePath
(
progress
:
CGFloat
)
->
UIBezierPath
{
private
func
dashLinePath
(
progress
:
CGFloat
)
->
UIBezierPath
{
var
pathProgress
=
max
(
0
,
progress
)
var
pathProgress
=
max
(
0
.04
,
progress
)
pathProgress
=
min
(
1
,
pathProgress
)
pathProgress
=
min
(
0.96
,
pathProgress
)
let
segment
=
dashCircleSegment
let
segment
=
dashCircleSegment
let
start
=
-
(
.
pi
-
segment
.
alpha
)
let
start
=
-
(
.
pi
-
segment
.
alpha
)
...
@@ -122,12 +151,14 @@ class CitySunCell: UITableViewCell {
...
@@ -122,12 +151,14 @@ class CitySunCell: UITableViewCell {
//Public
//Public
public
func
updateSunPosition
()
{
public
func
updateSunPosition
()
{
contentView
.
layoutIfNeeded
()
sunImageView
.
layer
.
removeAnimation
(
forKey
:
"sun.position"
)
sunImageView
.
layer
.
removeAnimation
(
forKey
:
"sun.position"
)
sunImageView
.
frame
.
origin
=
.
init
(
x
:
20
-
sunImageView
.
frame
.
width
/
2
,
sunImageView
.
frame
.
origin
=
.
init
(
x
:
20
-
sunImageView
.
frame
.
width
/
2
,
y
:
infographicContainer
.
frame
.
height
-
sunImageView
.
frame
.
height
/
2
)
y
:
infographicContainer
.
frame
.
height
-
sunImageView
.
frame
.
height
)
let
animation
=
CAKeyframeAnimation
(
keyPath
:
"position"
)
let
animation
=
CAKeyframeAnimation
(
keyPath
:
"position"
)
animation
.
path
=
self
.
dashLinePath
(
progress
:
0.7
)
.
cgPath
animation
.
path
=
self
.
dashLinePath
(
progress
:
sunProgress
)
.
cgPath
animation
.
calculationMode
=
.
paced
animation
.
calculationMode
=
.
paced
animation
.
duration
=
1.3
animation
.
duration
=
1.3
animation
.
rotationMode
=
.
rotateAuto
animation
.
rotationMode
=
.
rotateAuto
...
@@ -233,42 +264,40 @@ private extension CitySunCell {
...
@@ -233,42 +264,40 @@ private extension CitySunCell {
}
}
//Start
//Start
let
sunUpImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun_up_arrow"
))
let
sunriseImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun_up_arrow"
))
sunUpImageView
.
contentMode
=
.
scaleAspectFit
sunriseImageView
.
contentMode
=
.
scaleAspectFit
sunUpImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunriseImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunActivityStartLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
sunriseTimeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
sunActivityStartLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunriseTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunActivityStartLabel
.
text
=
"6:11 AM"
sunriseTimeLabel
.
textAlignment
=
.
left
sunActivityStartLabel
.
textAlignment
=
.
left
sunActivityContainer
.
addSubview
(
sunriseImageView
)
sunActivityContainer
.
addSubview
(
sunUpImageView
)
sunActivityContainer
.
addSubview
(
sunriseTimeLabel
)
sunActivityContainer
.
addSubview
(
sunActivityStartLabel
)
sunriseImageView
.
snp
.
makeConstraints
{
(
make
)
in
sunUpImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
top
.
equalToSuperview
()
.
inset
(
20
)
make
.
left
.
top
.
equalToSuperview
()
.
inset
(
20
)
}
}
sun
ActivityStart
Label
.
snp
.
makeConstraints
{
(
make
)
in
sun
riseTime
Label
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalTo
(
sun
Up
ImageView
.
snp
.
right
)
.
offset
(
3
)
make
.
left
.
equalTo
(
sun
rise
ImageView
.
snp
.
right
)
.
offset
(
3
)
make
.
centerY
.
equalTo
(
sun
Up
ImageView
)
make
.
centerY
.
equalTo
(
sun
rise
ImageView
)
}
}
//End
//End
let
sunDownImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun_down_arrow"
))
let
sunsetImageView
=
UIImageView
(
image
:
UIImage
(
named
:
"sun_down_arrow"
))
sunDownImageView
.
contentMode
=
.
scaleAspectFit
sunsetImageView
.
contentMode
=
.
scaleAspectFit
sunDownImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunsetImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunActivityEndLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
sunsetTimeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
sunActivityEndLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunsetTimeLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
sunActivityEndLabel
.
text
=
"6:23 PM"
sunsetTimeLabel
.
textAlignment
=
.
right
sunActivityEndLabel
.
textAlignment
=
.
right
sunActivityContainer
.
addSubview
(
sunsetImageView
)
sunActivityContainer
.
addSubview
(
sunDownImageView
)
sunActivityContainer
.
addSubview
(
sunsetTimeLabel
)
sunActivityContainer
.
addSubview
(
sunActivityEndLabel
)
sunsetTimeLabel
.
snp
.
makeConstraints
{
(
make
)
in
sunActivityEndLabel
.
snp
.
makeConstraints
{
(
make
)
in
make
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
right
.
equalToSuperview
()
.
inset
(
20
)
make
.
centerY
.
equalTo
(
sun
ActivityStart
Label
)
make
.
centerY
.
equalTo
(
sun
riseTime
Label
)
}
}
sun
Down
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
sun
set
ImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
right
.
equalTo
(
sun
ActivityEnd
Label
.
snp
.
left
)
.
inset
(
-
3
)
make
.
right
.
equalTo
(
sun
setTime
Label
.
snp
.
left
)
.
inset
(
-
3
)
make
.
centerY
.
equalTo
(
sun
Up
ImageView
)
make
.
centerY
.
equalTo
(
sun
rise
ImageView
)
}
}
//UV levels
//UV levels
...
@@ -277,7 +306,7 @@ private extension CitySunCell {
...
@@ -277,7 +306,7 @@ private extension CitySunCell {
sunUvView
.
snp
.
makeConstraints
{
(
make
)
in
sunUvView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
18
)
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
18
)
make
.
height
.
equalTo
(
8
)
make
.
height
.
equalTo
(
8
)
make
.
top
.
equalTo
(
sun
Up
ImageView
.
snp
.
bottom
)
.
offset
(
20
)
make
.
top
.
equalTo
(
sun
rise
ImageView
.
snp
.
bottom
)
.
offset
(
20
)
}
}
//UL label
//UL label
...
@@ -292,10 +321,10 @@ private extension CitySunCell {
...
@@ -292,10 +321,10 @@ private extension CitySunCell {
//Separator
//Separator
sunActivityContainer
.
addSubview
(
sunUvLineView
)
sunActivityContainer
.
addSubview
(
sunUvLineView
)
sunUvLineView
.
snp
.
makeConstraints
{
(
make
)
in
sunUvLineView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalTo
(
sun
ActivityStart
Label
.
snp
.
right
)
.
offset
(
8
)
make
.
left
.
equalTo
(
sun
riseTime
Label
.
snp
.
right
)
.
offset
(
8
)
make
.
right
.
equalTo
(
sun
Down
ImageView
.
snp
.
left
)
.
offset
(
-
8
)
make
.
right
.
equalTo
(
sun
set
ImageView
.
snp
.
left
)
.
offset
(
-
8
)
make
.
height
.
equalTo
(
8
)
make
.
height
.
equalTo
(
8
)
make
.
centerY
.
equalTo
(
sun
ActivityStart
Label
)
make
.
centerY
.
equalTo
(
sun
riseTime
Label
)
}
}
}
}
}
}
1Weather/UI/View controllers/Today/Cells/TodayCellFactory.swift
View file @
27d0bb5a
...
@@ -70,9 +70,11 @@ class TodayCellFactory {
...
@@ -70,9 +70,11 @@ class TodayCellFactory {
return
cell
return
cell
case
.
sun
:
case
.
sun
:
let
cell
=
dequeueReusableCell
(
type
:
CitySunCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
let
cell
=
dequeueReusableCell
(
type
:
CitySunCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
configure
(
with
:
loc
)
return
cell
return
cell
case
.
moon
:
case
.
moon
:
let
cell
=
dequeueReusableCell
(
type
:
CityMoonCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
let
cell
=
dequeueReusableCell
(
type
:
CityMoonCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
configure
(
with
:
loc
)
return
cell
return
cell
}
}
}
}
...
...
1Weather/UI/View controllers/Today/TodayViewController.swift
View file @
27d0bb5a
...
@@ -10,6 +10,7 @@ import CoreLocation
...
@@ -10,6 +10,7 @@ import CoreLocation
class
TodayViewController
:
UIViewController
{
class
TodayViewController
:
UIViewController
{
//Private
//Private
private
let
cityButton
=
NavigationCityButton
()
private
let
viewModel
:
TodayViewModel
private
let
viewModel
:
TodayViewModel
private
let
tableView
=
UITableView
()
private
let
tableView
=
UITableView
()
private
var
localizationObserver
:
Any
?
private
var
localizationObserver
:
Any
?
...
@@ -68,7 +69,7 @@ private extension TodayViewController {
...
@@ -68,7 +69,7 @@ private extension TodayViewController {
func
prepareNavigationBar
()
{
func
prepareNavigationBar
()
{
//City button
//City button
let
cityButton
=
NavigationCityButton
()
cityButton
.
isHidden
=
true
cityButton
.
addTarget
(
self
,
action
:
#selector(
handleCityButton
)
,
for
:
.
touchUpInside
)
cityButton
.
addTarget
(
self
,
action
:
#selector(
handleCityButton
)
,
for
:
.
touchUpInside
)
let
cityBarItem
=
UIBarButtonItem
(
customView
:
cityButton
)
let
cityBarItem
=
UIBarButtonItem
(
customView
:
cityButton
)
...
@@ -124,8 +125,11 @@ extension TodayViewController: UITableViewDelegate {
...
@@ -124,8 +125,11 @@ extension TodayViewController: UITableViewDelegate {
}
}
}
}
//MARK:- ViewModel Delegate
extension
TodayViewController
:
ViewModelDelegate
{
extension
TodayViewController
:
ViewModelDelegate
{
func
viewModelDidChange
<
P
>
(
model
:
P
)
where
P
:
ViewModelProtocol
{
func
viewModelDidChange
<
P
>
(
model
:
P
)
where
P
:
ViewModelProtocol
{
cityButton
.
configure
(
with
:
viewModel
.
location
)
cityButton
.
isHidden
=
false
tableView
.
reloadData
()
tableView
.
reloadData
()
}
}
}
}
1Weather/ViewModels/TodayViewModel.swift
View file @
27d0bb5a
...
@@ -6,11 +6,14 @@
...
@@ -6,11 +6,14 @@
//
//
import
UIKit
import
UIKit
class
TodayViewModel
:
ViewModelProtocol
{
class
TodayViewModel
:
ViewModelProtocol
{
//Public
//Public
public
let
todayCellFactory
=
TodayCellFactory
()
public
let
todayCellFactory
=
TodayCellFactory
()
public
weak
var
delegate
:
ViewModelDelegate
?
public
weak
var
delegate
:
ViewModelDelegate
?
public
private(set)
var
location
:
Location
?
public
private(set)
var
location
:
Location
?
//Private
private
var
locationManager
:
LocationManager
private
var
locationManager
:
LocationManager
public
init
(
locationManager
:
LocationManager
)
{
public
init
(
locationManager
:
LocationManager
)
{
...
...
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