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
7ca65c2c
Commit
7ca65c2c
authored
Apr 26, 2021
by
Dmitriy Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished radar time line animation
parent
f14dbb96
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
217 additions
and
96 deletions
+217
-96
1Weather.xcodeproj/project.pbxproj
+4
-4
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+0
-18
1Weather/Extensions/CACornerMask+All.swift
+14
-0
1Weather/Extensions/Date+TimeZoneConvert.swift
+0
-15
1Weather/Model/RadarLayers/SevereLayerType.swift
+28
-0
1Weather/UI/View controllers/Radar/MapTimeControl/MapCurrentTimeView.swift
+12
-0
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeControlItem.swift
+1
-0
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeControlView.swift
+86
-8
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeView.swift
+2
-3
1Weather/UI/View controllers/Radar/RadarMapLayersController.swift
+1
-0
1Weather/UI/View controllers/Radar/RadarViewController.swift
+52
-34
1Weather/ViewModels/RadarViewModel.swift
+1
-2
PG.playground/Contents.swift
+0
-7
Pods/Swarm/Swarm/SwarmOverlay.swift
+16
-5
No files found.
1Weather.xcodeproj/project.pbxproj
View file @
7ca65c2c
...
...
@@ -60,6 +60,7 @@
CD39F2F525DE9571009FE398
/* ArrowButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD39F2F425DE9571009FE398
/* ArrowButton.swift */
;
};
CD3F6E6925FA59D4002DB99B
/* ForecastDetailPeriodButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3F6E6825FA59D4002DB99B
/* ForecastDetailPeriodButton.swift */
;
};
CD3F6E6C25FA5A90002DB99B
/* PeriodButtonProtocol.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD3F6E6B25FA5A90002DB99B
/* PeriodButtonProtocol.swift */
;
};
CD43DF032636C6640010C9F7
/* CACornerMask+All.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD43DF022636C6640010C9F7
/* CACornerMask+All.swift */
;
};
CD4742D0261200500061AC95
/* TodayAlertCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD4742CF261200500061AC95
/* TodayAlertCell.swift */
;
};
CD55E0BB2615EE2400CC4DC7
/* PollutantView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD55E0BA2615EE2400CC4DC7
/* PollutantView.swift */
;
};
CD593BC226088A5900C93428
/* TimePeriodOffsetHolder.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD593BC126088A5900C93428
/* TimePeriodOffsetHolder.swift */
;
};
...
...
@@ -128,7 +129,6 @@
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 */
;
};
CDD17E2E263300CF00E92B6A
/* Date+TimeZoneConvert.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDD17E2D263300CF00E92B6A
/* Date+TimeZoneConvert.swift */
;
};
CDD75F0D25DE68B10099ACDB
/* Localizable.strings in Resources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDD75F0F25DE68B10099ACDB
/* Localizable.strings */
;
};
CDDE8D7C262EED3C00267931
/* MapLegendSevereView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDDE8D7B262EED3C00267931
/* MapLegendSevereView.swift */
;
};
CDDE8D7F262EED4D00267931
/* MapLegendWeatherView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDDE8D7E262EED4D00267931
/* MapLegendWeatherView.swift */
;
};
...
...
@@ -269,6 +269,7 @@
CD39F2F425DE9571009FE398
/* ArrowButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ArrowButton.swift
;
sourceTree
=
"<group>"
;
};
CD3F6E6825FA59D4002DB99B
/* ForecastDetailPeriodButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastDetailPeriodButton.swift
;
sourceTree
=
"<group>"
;
};
CD3F6E6B25FA5A90002DB99B
/* PeriodButtonProtocol.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PeriodButtonProtocol.swift
;
sourceTree
=
"<group>"
;
};
CD43DF022636C6640010C9F7
/* CACornerMask+All.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"CACornerMask+All.swift"
;
sourceTree
=
"<group>"
;
};
CD4742CF261200500061AC95
/* TodayAlertCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
TodayAlertCell.swift
;
sourceTree
=
"<group>"
;
};
CD55E0BA2615EE2400CC4DC7
/* PollutantView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PollutantView.swift
;
sourceTree
=
"<group>"
;
};
CD593BC126088A5900C93428
/* TimePeriodOffsetHolder.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
TimePeriodOffsetHolder.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -337,7 +338,6 @@
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>"
;
};
CDD17E2D263300CF00E92B6A
/* Date+TimeZoneConvert.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"Date+TimeZoneConvert.swift"
;
sourceTree
=
"<group>"
;
};
CDD75F0E25DE68B10099ACDB
/* en */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
text.plist.strings
;
name
=
en
;
path
=
en.lproj/Localizable.strings
;
sourceTree
=
"<group>"
;
};
CDDE8D7B262EED3C00267931
/* MapLegendSevereView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MapLegendSevereView.swift
;
sourceTree
=
"<group>"
;
};
CDDE8D7E262EED4D00267931
/* MapLegendWeatherView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MapLegendWeatherView.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -536,7 +536,7 @@
CDF4808E261727E00076E9F5
/* CLAuthorizationStatus+Localized.swift */
,
CDF48091261729680076E9F5
/* UIApplication+Settings.swift */
,
CD67616C262587D30079D273
/* UITabBarController+Hide.swift */
,
CD
D17E2D263300CF00E92B6A
/* Date+TimeZoneConvert
.swift */
,
CD
43DF022636C6640010C9F7
/* CACornerMask+All
.swift */
,
);
path
=
Extensions
;
sourceTree
=
"<group>"
;
...
...
@@ -1334,6 +1334,7 @@
CDD0F1E82572429E00CF5017
/* AppFont.swift in Sources */
,
CE8962AA26175DF500CA274A
/* CoreAirQuality.swift in Sources */
,
CE28475D2615A5B3006C8DC5
/* Health.swift in Sources */
,
CD43DF032636C6640010C9F7
/* CACornerMask+All.swift in Sources */
,
CEF9599F2601DF3300975FAA
/* AdLogger.swift in Sources */
,
CDC6124F25E7964700188DA7
/* TodayDayTimesCell.swift in Sources */
,
CD593BC226088A5900C93428
/* TimePeriodOffsetHolder.swift in Sources */
,
...
...
@@ -1443,7 +1444,6 @@
CD55E0BB2615EE2400CC4DC7
/* PollutantView.swift in Sources */
,
CDDE8D7C262EED3C00267931
/* MapLegendSevereView.swift in Sources */
,
CD6761882625C3360079D273
/* RadarViewModel.swift in Sources */
,
CDD17E2E263300CF00E92B6A
/* Date+TimeZoneConvert.swift in Sources */
,
CDF8F12A262089A200DB384A
/* MapTimeView.swift in Sources */
,
CEC526FA25E7959A00DA58A5
/* WeatherSource.swift in Sources */
,
CDF4808F261727E00076E9F5
/* CLAuthorizationStatus+Localized.swift in Sources */
,
...
...
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
View file @
7ca65c2c
...
...
@@ -3,22 +3,4 @@
uuid =
"55281C35-FE9F-4CED-865E-FBED0E7393F6"
type =
"0"
version =
"2.0"
>
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID =
"Xcode.Breakpoint.FileBreakpoint"
>
<BreakpointContent
uuid =
"03921A78-9DF4-4BDE-88B6-E44035BF9063"
shouldBeEnabled =
"Yes"
ignoreCount =
"0"
continueAfterRunningActions =
"No"
filePath =
"1Weather/Extensions/Calendar+TimeZone.swift"
startingColumnNumber =
"9223372036854775807"
endingColumnNumber =
"9223372036854775807"
startingLineNumber =
"21"
endingLineNumber =
"21"
landmarkName =
"isNow(fromDate:timeZone:)"
landmarkType =
"7"
>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
1Weather/Extensions/CACornerMask+All.swift
0 → 100644
View file @
7ca65c2c
//
// CACornerMask+All.swift
// 1Weather
//
// Created by Dmitry Stepanets on 26.04.2021.
//
import
UIKit
extension
CACornerMask
{
static
var
all
:
CACornerMask
{
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
,
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
}
}
1Weather/Extensions/Date+TimeZoneConvert.swift
deleted
100644 → 0
View file @
f14dbb96
//
// Date+TimeZoneConvert.swift
// 1Weather
//
// Created by Dmitry Stepanets on 23.04.2021.
//
import
Foundation
extension
Date
{
func
convert
(
from
initTimeZone
:
TimeZone
,
to
targetTimeZone
:
TimeZone
)
->
Date
{
let
delta
=
TimeInterval
(
targetTimeZone
.
secondsFromGMT
(
for
:
self
)
-
initTimeZone
.
secondsFromGMT
(
for
:
self
))
return
addingTimeInterval
(
delta
)
}
}
1Weather/Model/RadarLayers/SevereLayerType.swift
View file @
7ca65c2c
...
...
@@ -6,6 +6,7 @@
//
import
UIKit
import
Swarm
public
enum
SevereLayerType
:
String
,
CaseIterable
,
RadarLayerType
{
case
fire
=
"radar.severeLayer.fire"
...
...
@@ -28,6 +29,33 @@ public enum SevereLayerType:String, CaseIterable, RadarLayerType {
return
self
.
rawValue
.
localized
()
}
var
swarmLayer
:
SwarmGroup
{
switch
self
{
case
.
fire
:
return
.
fire
case
.
floods
:
return
.
flood
case
.
fog
:
return
.
fog
case
.
freezing
:
return
.
freezing
case
.
hurricaneTropical
:
return
.
hurricaneAndTropical
case
.
hurricaneTropicalTracks
:
return
.
hurricaneTracks
case
.
ice
:
return
.
ice
case
.
snow
:
return
.
snow
case
.
stormTornados
:
return
.
stormAndTornadoes
case
.
wind
:
return
.
wind
case
.
winter
:
return
.
winter
}
}
var
values
:[
String
]
{
switch
self
{
case
.
fire
:
...
...
1Weather/UI/View controllers/Radar/MapTimeControl/MapCurrentTimeView.swift
View file @
7ca65c2c
...
...
@@ -11,6 +11,11 @@ class MapCurrentTimeView: UIView {
private
let
imageView
=
UIImageView
()
private
let
valueLabel
=
UILabel
()
private
let
timeLabel
=
UILabel
()
private
static
var
timeFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"h:mm a"
return
fmt
}()
init
()
{
super
.
init
(
frame
:
.
zero
)
...
...
@@ -20,6 +25,12 @@ class MapCurrentTimeView: UIView {
prepareLabels
()
}
public
func
configure
(
timeItem
:
MapTimeControlItem
)
{
MapCurrentTimeView
.
timeFormatter
.
timeZone
=
timeItem
.
timeZone
valueLabel
.
text
=
""
timeLabel
.
text
=
MapCurrentTimeView
.
timeFormatter
.
string
(
from
:
timeItem
.
date
)
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
...
...
@@ -49,6 +60,7 @@ private extension MapCurrentTimeView {
valueLabel
.
setContentHuggingPriority
(
.
fittingSizeLevel
,
for
:
.
vertical
)
addSubview
(
valueLabel
)
timeLabel
.
textAlignment
=
.
center
timeLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
10
)
timeLabel
.
textColor
=
.
white
timeLabel
.
text
=
"2:50 PM"
...
...
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeControlItem.swift
View file @
7ca65c2c
...
...
@@ -10,4 +10,5 @@ import Foundation
struct
MapTimeControlItem
{
let
value
:
String
let
date
:
Date
let
timeZone
:
TimeZone
}
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeControlView.swift
View file @
7ca65c2c
...
...
@@ -8,6 +8,17 @@
import
UIKit
import
SnapKit
protocol
MapTimeControlViewDelegate
:
class
{
func
didSelectPlayButton
()
func
didSelectPauseButton
()
func
didSelect
(
item
:
MapTimeControlItem
)
}
private
enum
PlayButtonState
{
case
play
case
pause
}
class
MapTimeControlView
:
UIView
{
//Private
private
let
container
=
UIView
()
...
...
@@ -17,7 +28,11 @@ class MapTimeControlView: UIView {
private
let
currenTimeView
=
MapCurrentTimeView
()
private
let
currentTimeDashLine
=
CAShapeLayer
()
private
let
progresView
=
UIView
()
private
var
progressWidthConstraint
:
Constraint
?
private
var
currentItems
=
[
MapTimeControlItem
]()
private
var
playButtonState
=
PlayButtonState
.
pause
//Public
weak
var
delegate
:
MapTimeControlViewDelegate
?
init
()
{
super
.
init
(
frame
:
.
zero
)
...
...
@@ -26,8 +41,8 @@ class MapTimeControlView: UIView {
prepareContainer
()
preparePlayButton
()
prepareStackView
()
prepareCurrentTimeView
()
prepareProgressView
()
prepareCurrentTimeView
()
updateUI
()
}
...
...
@@ -65,15 +80,68 @@ class MapTimeControlView: UIView {
}
public
func
configure
(
items
:[
MapTimeControlItem
],
timeZone
:
TimeZone
)
{
//Reduce count if needed
if
items
.
count
>
5
{
var
modifiedItems
=
items
while
modifiedItems
.
count
>
5
{
let
centerIndex
=
modifiedItems
.
count
/
2
modifiedItems
.
remove
(
at
:
centerIndex
)
}
self
.
currentItems
=
modifiedItems
}
else
{
self
.
currentItems
=
items
}
stackView
.
removeAll
()
i
tems
.
forEach
{
self
.
currentI
tems
.
forEach
{
let
view
=
MapTimeView
(
item
:
$0
)
stackView
.
addArrangedSubview
(
view
)
}
stackView
.
layoutIfNeeded
()
}
public
func
updateProgress
(
value
:
CGFloat
)
{
var
progress
=
max
(
0
,
value
)
progress
=
min
(
1
,
progress
)
currenTimeView
.
isHidden
=
false
currentTimeDashLine
.
isHidden
=
false
progresView
.
layer
.
maskedCorners
=
progress
<
1
?
[
.
layerMinXMinYCorner
,
.
layerMinXMaxYCorner
]
:
.
all
updateCurrentViewWith
(
proress
:
progress
)
currenTimeView
.
snp
.
updateConstraints
{
(
update
)
in
switch
progress
{
case
0
:
update
.
centerX
.
equalTo
(
progresView
.
snp
.
right
)
.
inset
(
-
50
)
case
1
:
update
.
centerX
.
equalTo
(
progresView
.
snp
.
right
)
.
offset
(
-
10
)
default
:
update
.
centerX
.
equalTo
(
progresView
.
snp
.
right
)
}
}
if
progress
==
0
{
progresView
.
snp
.
remakeConstraints
{
(
remake
)
in
remake
.
left
.
top
.
bottom
.
equalToSuperview
()
remake
.
width
.
equalToSuperview
()
.
multipliedBy
(
0
)
}
return
}
progresView
.
snp
.
remakeConstraints
{(
remake
)
in
remake
.
left
.
top
.
bottom
.
equalToSuperview
()
remake
.
width
.
equalToSuperview
()
.
multipliedBy
(
progress
)
}
}
private
func
updateCurrentViewWith
(
proress
:
CGFloat
)
{
let
targetIndex
=
Int
(
CGFloat
(
currentItems
.
count
-
1
)
*
proress
)
let
item
=
currentItems
[
targetIndex
]
currenTimeView
.
configure
(
timeItem
:
item
)
}
private
func
updateUI
()
{
container
.
backgroundColor
=
ThemeManager
.
currentTheme
.
mapControlsColor
...
...
@@ -86,7 +154,16 @@ class MapTimeControlView: UIView {
}
@objc
private
func
handlePlayButton
()
{
switch
playButtonState
{
case
.
play
:
playButton
.
setImage
(
UIImage
(
named
:
"pause_icon"
),
for
:
.
normal
)
delegate
?
.
didSelectPlayButton
()
self
.
playButtonState
=
.
pause
case
.
pause
:
playButton
.
setImage
(
UIImage
(
named
:
"play_icon"
),
for
:
.
normal
)
delegate
?
.
didSelectPauseButton
()
self
.
playButtonState
=
.
play
}
}
}
...
...
@@ -111,7 +188,7 @@ private extension MapTimeControlView {
}
func
preparePlayButton
()
{
playButton
.
setImage
(
UIImage
(
named
:
"p
lay
_icon"
),
for
:
.
normal
)
playButton
.
setImage
(
UIImage
(
named
:
"p
ause
_icon"
),
for
:
.
normal
)
playButton
.
tintColor
=
ThemeManager
.
currentTheme
.
graphTintColor
playButton
.
layer
.
shadowColor
=
UIColor
.
black
.
withAlphaComponent
(
0.12
)
.
cgColor
playButton
.
layer
.
shadowOffset
=
.
init
(
width
:
0
,
height
:
3
)
...
...
@@ -145,14 +222,16 @@ private extension MapTimeControlView {
}
func
prepareCurrentTimeView
()
{
currenTimeView
.
isHidden
=
true
addSubview
(
currenTimeView
)
currenTimeView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
top
.
equalToSuperview
()
make
.
bottom
.
equalTo
(
container
.
snp
.
top
)
make
.
centerX
.
equalTo
Superview
(
)
make
.
centerX
.
equalTo
(
progresView
.
snp
.
right
)
}
//Dash line
currentTimeDashLine
.
isHidden
=
true
currentTimeDashLine
.
lineWidth
=
1
currentTimeDashLine
.
strokeColor
=
ThemeManager
.
currentTheme
.
graphTintColor
.
cgColor
currentTimeDashLine
.
lineDashPattern
=
[
2
,
2
]
...
...
@@ -161,13 +240,12 @@ private extension MapTimeControlView {
func
prepareProgressView
()
{
progresView
.
layer
.
cornerRadius
=
container
.
layer
.
cornerRadius
progresView
.
layer
.
maskedCorners
=
[
.
layerMinXMinYCorner
,
.
layerMinXMaxYCorner
]
progresView
.
backgroundColor
=
ThemeManager
.
currentTheme
.
graphTintColor
.
withAlphaComponent
(
0.2
)
container
.
insertSubview
(
progresView
,
belowSubview
:
playButton
)
progresView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
top
.
bottom
.
equalToSuperview
()
self
.
progressWidthConstraint
=
make
.
width
.
equalToSuperview
()
.
multipliedBy
(
0.5
)
.
constraint
make
.
width
.
equalToSuperview
()
.
multipliedBy
(
0
)
}
}
}
1Weather/UI/View controllers/Radar/MapTimeControl/MapTimeView.swift
View file @
7ca65c2c
...
...
@@ -10,7 +10,7 @@ import UIKit
class
MapTimeView
:
UIView
{
private
let
valueLabel
=
UILabel
()
private
let
timeLabel
=
UILabel
()
private
static
let
timeFormatter
:
DateFormatter
=
{
private
static
var
timeFormatter
:
DateFormatter
=
{
let
fmt
=
DateFormatter
()
fmt
.
dateFormat
=
"h:mm"
return
fmt
...
...
@@ -23,6 +23,7 @@ class MapTimeView: UIView {
updateUI
()
valueLabel
.
text
=
item
.
value
MapTimeView
.
timeFormatter
.
timeZone
=
item
.
timeZone
timeLabel
.
text
=
MapTimeView
.
timeFormatter
.
string
(
from
:
item
.
date
)
}
...
...
@@ -50,11 +51,9 @@ class MapTimeView: UIView {
//MARK:- Prepare
private
extension
MapTimeView
{
func
prepareLabels
()
{
valueLabel
.
text
=
"45°"
valueLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
10
)
addSubview
(
valueLabel
)
timeLabel
.
text
=
"2:00"
timeLabel
.
textAlignment
=
.
center
timeLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
14
)
timeLabel
.
setContentCompressionResistancePriority
(
.
fittingSizeLevel
,
for
:
.
vertical
)
...
...
1Weather/UI/View controllers/Radar/RadarMapLayersController.swift
View file @
7ca65c2c
...
...
@@ -156,6 +156,7 @@ extension RadarMapLayersController: UITableViewDelegate {
func
tableView
(
_
tableView
:
UITableView
,
didSelectRowAt
indexPath
:
IndexPath
)
{
cellFactory
.
didSelectRow
(
indexPath
:
indexPath
)
tableView
.
reloadData
()
self
.
handleCloseButton
()
}
}
...
...
1Weather/UI/View controllers/Radar/RadarViewController.swift
View file @
7ca65c2c
...
...
@@ -32,7 +32,6 @@ class RadarViewController: UIViewController {
if
let
overlay
=
swarmOverlay
{
overlay
.
startUpdating
(
block
:
{
[
weak
self
]
(
dataAvailable
,
updateError
)
in
self
?
.
swarmRenderer
?
.
setNeedsDisplay
()
// print("[SWARM] Updating: \(String(describing: self?.updateDateLabel()))")
})
mapView
.
addOverlay
(
overlay
,
level
:
.
aboveRoads
)
swarmRenderer
?
.
setNeedsDisplay
()
// forces overlay to update to latest radar view
...
...
@@ -116,34 +115,42 @@ class RadarViewController: UIViewController {
return
}
var
rawOverlay
:
SwarmOverlay
?
if
let
weatherLayer
=
selectedLayer
.
layer
as?
WeatherLayerType
{
let
overlay
=
SwarmManager
.
sharedManager
.
overlayForGroup
(
.
none
,
baseLayer
:
weatherLayer
.
swarmLayer
)
rawOverlay
=
SwarmManager
.
sharedManager
.
overlayForBaseLayer
(
weatherLayer
.
swarmLayer
)
// This is needed to use enhanced styles for international radar
if
weatherLayer
.
swarmLayer
==
.
satellite
{
overlay
.
style
=
"enhanced"
rawOverlay
?
.
style
=
"enhanced"
}
}
if
let
severeLayer
=
selectedLayer
.
layer
as?
SevereLayerType
{
rawOverlay
=
SwarmManager
.
sharedManager
.
overlayForGroup
(
severeLayer
.
swarmLayer
,
baseLayer
:
.
radar
)
}
guard
let
overlay
=
rawOverlay
else
{
return
}
// set this offset to 1 to animate at lower zoom level (loads fewer tiles, faster), 0 is normal
overlay
.
loopZoomOffset
=
0
overlay
.
alpha
=
0.85
//overlay.debug = true
overlay
.
queryTimes
{[
weak
self
]
(
_
,
error
)
in
guard
let
self
=
self
else
{
return
}
// set this offset to 1 to animate at lower zoom level (loads fewer tiles, faster), 0 is normal
overlay
.
loopZoomOffset
=
0
overlay
.
alpha
=
0.85
// overlay.debug = true
self
.
swarmOverlay
=
overlay
overlay
.
queryTimes
{[
weak
self
]
(
_
,
error
)
in
guard
let
self
=
self
else
{
return
}
self
.
swarmOverlay
=
overlay
//Update timeline
if
let
validTimes
=
overlay
.
validTimes
as?
[
String
:
AnyObject
]
{
let
dates
=
validTimes
.
map
{
$0
.
value
}
.
first
as?
[
String
]
if
let
stringArray
=
dates
{
let
items
=
self
.
radarViewModel
.
buildTimelineValuesFor
(
validTimes
:
stringArray
)
if
let
timeZone
=
self
.
radarViewModel
.
location
?
.
timeZone
{
self
.
mapTimeControlView
.
configure
(
items
:
items
,
timeZone
:
timeZone
)
}
//Update timeline
if
let
validTimes
=
overlay
.
validTimes
as?
[
String
:
AnyObject
]
{
let
dates
=
validTimes
.
map
{
$0
.
value
}
.
first
as?
[
String
]
if
let
stringArray
=
dates
{
let
items
=
self
.
radarViewModel
.
buildTimelineValuesFor
(
validTimes
:
stringArray
)
if
let
timeZone
=
self
.
radarViewModel
.
location
?
.
timeZone
{
self
.
mapTimeControlView
.
configure
(
items
:
items
,
timeZone
:
timeZone
)
self
.
mapTimeControlView
.
updateProgress
(
value
:
0
)
}
}
// _ = self.updateDateLabel()
}
}
}
...
...
@@ -156,18 +163,15 @@ class RadarViewController: UIViewController {
private
func
beginLoop
()
{
guard
let
overlay
=
swarmOverlay
else
{
return
}
// progressView.isHidden = false
// progressView.progress = 0.0
// playButton.setImage(UIImage(named: "pause_white"), for: .normal)
// playButton.accessibilityLabel = "Pause".localized
DispatchQueue
.
global
(
qos
:
.
userInitiated
)
.
async
{
/*self.progress*/
_
=
overlay
.
fetchTilesForAnimation
(
self
.
mapView
.
visibleMapRect
,
readyBlock
:
{
[
weak
self
]
in
guard
let
strongSelf
=
self
else
{
return
}
strongSelf
.
swarmOverlay
?
.
startAnimating
({(
_
)
in
// let _ = self?.updateDateLabel() ?? ""
// print("Animation: \(time)")
self
?
.
swarmRenderer
?
.
setNeedsDisplay
()
//setNeedsDisplayInMapRect((self?.mapView.visibleMapRect)!)
strongSelf
.
swarmOverlay
?
.
startAnimating
({
(
_
)
in
self
?
.
swarmRenderer
?
.
setNeedsDisplay
()
},
{
(
currentFrame
,
totalFrames
)
in
strongSelf
.
mapTimeControlView
.
updateProgress
(
value
:
CGFloat
(
currentFrame
)
/
CGFloat
(
totalFrames
))
})
})
}
...
...
@@ -175,11 +179,8 @@ class RadarViewController: UIViewController {
private
func
endLoop
()
{
DispatchQueue
.
global
(
qos
:
.
userInitiated
)
.
async
{
self
.
swarmOverlay
?
.
stopAnimating
(
jumpToLastFrame
:
tru
e
)
self
.
swarmOverlay
?
.
stopAnimating
(
jumpToLastFrame
:
fals
e
)
}
// progressView.isHidden = true
// playButton.setImage(UIImage(named: "play_white"), for: .normal)
// playButton.accessibilityLabel = "Play".localized
swarmRenderer
?
.
setNeedsDisplay
(
mapView
.
visibleMapRect
)
}
...
...
@@ -335,6 +336,7 @@ private extension RadarViewController {
}
func
prepareMapTimeControl
()
{
mapTimeControlView
.
delegate
=
self
view
.
insertSubview
(
mapTimeControlView
,
belowSubview
:
legendView
)
mapTimeControlView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalToSuperview
()
.
inset
(
4
)
...
...
@@ -354,6 +356,7 @@ extension RadarViewController: RadarViewModelDelegate {
func
viewModel
(
model
:
RadarViewModel
,
didSelectLayer
layer
:
RadarLayer
)
{
pinnedLayersView
.
selectLayer
(
radarLayer
:
layer
)
legendView
.
configure
(
radarLayer
:
layer
)
setOverlay
()
}
func
viewModelPinnedLayersDidChange
(
model
:
RadarViewModel
)
{
...
...
@@ -399,3 +402,18 @@ extension RadarViewController: MapPinnedLayersViewDelegate {
radarViewModel
.
select
(
layerId
:
layerId
)
}
}
//MARK:- MapTimeControleView Delegate
extension
RadarViewController
:
MapTimeControlViewDelegate
{
func
didSelectPlayButton
()
{
beginLoop
()
}
func
didSelectPauseButton
()
{
endLoop
()
}
func
didSelect
(
item
:
MapTimeControlItem
)
{
//
}
}
1Weather/ViewModels/RadarViewModel.swift
View file @
7ca65c2c
...
...
@@ -106,8 +106,7 @@ class RadarViewModel: ViewModelProtocol {
continue
}
let
timeZoneDate
=
validDate
.
convert
(
from
:
locationTimeZone
,
to
:
TimeZone
(
secondsFromGMT
:
0
)
!
)
items
.
append
(
.
init
(
value
:
""
,
date
:
timeZoneDate
))
items
.
append
(
.
init
(
value
:
""
,
date
:
validDate
,
timeZone
:
locationTimeZone
))
// for hourlyWeather in hourly {
// if validDate == hourlyWeather.date {
...
...
PG.playground/Contents.swift
View file @
7ca65c2c
import
Foundation
import
UIKit
let
far
=
Measurement
<
UnitTemperature
>
(
value
:
50
,
unit
:
.
fahrenheit
)
let
fmt
=
MeasurementFormatter
()
fmt
.
unitStyle
=
.
long
fmt
.
unitOptions
=
.
providedUnit
fmt
.
string
(
from
:
far
.
converted
(
to
:
.
kelvin
))
Pods/Swarm/Swarm/SwarmOverlay.swift
View file @
7ca65c2c
...
...
@@ -315,12 +315,17 @@ extension SwarmOverlay {
public
func
stopUpdating
()
{
updateTimer
?
.
invalidate
();
updateTimer
=
nil
}
public
func
startAnimating
(
_
onFrameChanged
:
@escaping
((
UIImage
?)
->
Void
))
{
public
func
startAnimating
(
_
onFrameChanged
:
@escaping
((
UIImage
?)
->
Void
),
_
onProgress
:((
_
currentFrame
:
Int
,
_
totalFrames
:
Int
)
->
Void
)?
=
nil
)
{
frameTimer
?
.
invalidate
()
frameTimer
=
Timer
.
repeatingBlockTimer
(
0.4
)
{
[
weak
self
]
in
guard
let
strongSelf
=
self
else
{
return
}
var
nextFrame
=
strongSelf
.
index
+
1
if
nextFrame
==
strongSelf
.
loopTimes
.
count
&&
strongSelf
.
frameDwell
==
0
{
onProgress
?(
nextFrame
,
strongSelf
.
loopTimes
.
count
)
}
if
(
nextFrame
>=
strongSelf
.
loopTimes
.
count
)
{
strongSelf
.
frameDwell
=
strongSelf
.
frameDwell
+
1
...
...
@@ -329,17 +334,23 @@ extension SwarmOverlay {
}
}
if
nextFrame
>=
strongSelf
.
loopTimes
.
count
{
strongSelf
.
frameDwell
=
0
;
nextFrame
=
0
}
if
nextFrame
>=
strongSelf
.
loopTimes
.
count
{
strongSelf
.
frameDwell
=
0
;
nextFrame
=
0
}
strongSelf
.
index
=
nextFrame
onFrameChanged
(
strongSelf
.
renderedImageCache
.
object
(
forKey
:
strongSelf
.
currentFrameTimestamp
as
AnyObject
)
as?
UIImage
)
onProgress
?(
nextFrame
,
strongSelf
.
loopTimes
.
count
)
}
}
public
func
stopAnimating
(
jumpToLastFrame
:
Bool
=
false
)
{
frameTimer
?
.
invalidate
();
frameTimer
=
nil
frameTimer
?
.
invalidate
()
frameTimer
=
nil
cancelLoading
()
if
jumpToLastFrame
{
frameDwell
=
dwellCount
;
index
=
loopTimes
.
count
-
1
}
if
jumpToLastFrame
{
frameDwell
=
dwellCount
index
=
loopTimes
.
count
-
1
}
}
public
func
pauseForMove
()
{
...
...
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