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
c7d6b24e
Commit
c7d6b24e
authored
Mar 30, 2021
by
Dmitriy Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changing the LocationController UI
parent
e6ea1f92
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
156 additions
and
112 deletions
+156
-112
1Weather.xcodeproj/project.pbxproj
+4
-1
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
1Weather/Coordinators/LocationSearchCoordinator.swift
+32
-0
1Weather/Coordinators/TodayCoordinator.swift
+7
-1
1Weather/Resources/Assets.xcassets/location_arrow.imageset/Contents.json
+16
-0
1Weather/Resources/Assets.xcassets/location_arrow.imageset/location_arrow.pdf
+0
-0
1Weather/Resources/en.lproj/Localizable.strings
+6
-0
1Weather/UI/View controllers/Locations/LocationViewController.swift
+85
-105
1Weather/UI/View controllers/Today/Cells/TodayForecastTimePeriodCell.swift
+1
-1
1Weather/UI/View controllers/Today/TodayViewController.swift
+5
-4
No files found.
1Weather.xcodeproj/project.pbxproj
View file @
c7d6b24e
...
@@ -115,6 +115,7 @@
...
@@ -115,6 +115,7 @@
CDE2BF222609D4250085C930
/* ForecastWindSpeedCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF212609D4250085C930
/* ForecastWindSpeedCell.swift */
;
};
CDE2BF222609D4250085C930
/* ForecastWindSpeedCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF212609D4250085C930
/* ForecastWindSpeedCell.swift */
;
};
CDE2BF252609D9140085C930
/* ForecastWindButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF242609D9140085C930
/* ForecastWindButton.swift */
;
};
CDE2BF252609D9140085C930
/* ForecastWindButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDE2BF242609D9140085C930
/* ForecastWindButton.swift */
;
};
CDEE8AD725DA882200C289DE
/* ForecastPeriodButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEE8AD625DA882200C289DE
/* ForecastPeriodButton.swift */
;
};
CDEE8AD725DA882200C289DE
/* ForecastPeriodButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDEE8AD625DA882200C289DE
/* ForecastPeriodButton.swift */
;
};
CDF9BF8E26133D050037847D
/* LocationSearchCoordinator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CDF9BF8D26133D050037847D
/* LocationSearchCoordinator.swift */
;
};
CE578FD325F7E89400E8B85D
/* DayTimeWeather.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FD225F7E89400E8B85D
/* DayTimeWeather.swift */
;
};
CE578FD325F7E89400E8B85D
/* DayTimeWeather.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FD225F7E89400E8B85D
/* DayTimeWeather.swift */
;
};
CE578FE525FB415F00E8B85D
/* CityCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FE225FB415F00E8B85D
/* CityCell.swift */
;
};
CE578FE525FB415F00E8B85D
/* CityCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FE225FB415F00E8B85D
/* CityCell.swift */
;
};
CE578FE625FB415F00E8B85D
/* LocationViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FE325FB415F00E8B85D
/* LocationViewController.swift */
;
};
CE578FE625FB415F00E8B85D
/* LocationViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE578FE325FB415F00E8B85D
/* LocationViewController.swift */
;
};
...
@@ -265,6 +266,7 @@
...
@@ -265,6 +266,7 @@
CDE2BF212609D4250085C930
/* ForecastWindSpeedCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastWindSpeedCell.swift
;
sourceTree
=
"<group>"
;
};
CDE2BF212609D4250085C930
/* ForecastWindSpeedCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastWindSpeedCell.swift
;
sourceTree
=
"<group>"
;
};
CDE2BF242609D9140085C930
/* ForecastWindButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastWindButton.swift
;
sourceTree
=
"<group>"
;
};
CDE2BF242609D9140085C930
/* ForecastWindButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastWindButton.swift
;
sourceTree
=
"<group>"
;
};
CDEE8AD625DA882200C289DE
/* ForecastPeriodButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastPeriodButton.swift
;
sourceTree
=
"<group>"
;
};
CDEE8AD625DA882200C289DE
/* ForecastPeriodButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastPeriodButton.swift
;
sourceTree
=
"<group>"
;
};
CDF9BF8D26133D050037847D
/* LocationSearchCoordinator.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
LocationSearchCoordinator.swift
;
sourceTree
=
"<group>"
;
};
CE578FD225F7E89400E8B85D
/* DayTimeWeather.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DayTimeWeather.swift
;
sourceTree
=
"<group>"
;
};
CE578FD225F7E89400E8B85D
/* DayTimeWeather.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DayTimeWeather.swift
;
sourceTree
=
"<group>"
;
};
CE578FE225FB415F00E8B85D
/* CityCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CityCell.swift
;
sourceTree
=
"<group>"
;
};
CE578FE225FB415F00E8B85D
/* CityCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
CityCell.swift
;
sourceTree
=
"<group>"
;
};
CE578FE325FB415F00E8B85D
/* LocationViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
LocationViewController.swift
;
sourceTree
=
"<group>"
;
};
CE578FE325FB415F00E8B85D
/* LocationViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
LocationViewController.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -448,6 +450,7 @@
...
@@ -448,6 +450,7 @@
CD32CE0A260C744A00235081
/* MenuCoordinator.swift */
,
CD32CE0A260C744A00235081
/* MenuCoordinator.swift */
,
CD37D3F2260DF4FB002669D6
/* SettingsCoordinator.swift */
,
CD37D3F2260DF4FB002669D6
/* SettingsCoordinator.swift */
,
CD866A75260F77C500E96A5C
/* SettingsDetailsCoordinator.swift */
,
CD866A75260F77C500E96A5C
/* SettingsDetailsCoordinator.swift */
,
CDF9BF8D26133D050037847D
/* LocationSearchCoordinator.swift */
,
);
);
path
=
Coordinators
;
path
=
Coordinators
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -1088,6 +1091,7 @@
...
@@ -1088,6 +1091,7 @@
CDE2BF252609D9140085C930
/* ForecastWindButton.swift in Sources */
,
CDE2BF252609D9140085C930
/* ForecastWindButton.swift in Sources */
,
CD32CE16260C77C600235081
/* MenuHeaderButton.swift in Sources */
,
CD32CE16260C77C600235081
/* MenuHeaderButton.swift in Sources */
,
CD251ED82603633800ED7A65
/* ForecastPrecipitationCell.swift in Sources */
,
CD251ED82603633800ED7A65
/* ForecastPrecipitationCell.swift in Sources */
,
CDF9BF8E26133D050037847D
/* LocationSearchCoordinator.swift in Sources */
,
CD86246125E662BC0097F3FB
/* SunUvLineView.swift in Sources */
,
CD86246125E662BC0097F3FB
/* SunUvLineView.swift in Sources */
,
CD32CE0B260C744A00235081
/* MenuCoordinator.swift in Sources */
,
CD32CE0B260C744A00235081
/* MenuCoordinator.swift in Sources */
,
CEC526FA25E7959A00DA58A5
/* WeatherSource.swift in Sources */
,
CEC526FA25E7959A00DA58A5
/* WeatherSource.swift in Sources */
,
...
@@ -1110,7 +1114,6 @@
...
@@ -1110,7 +1114,6 @@
CD17C5F625D15B4400EE884E
/* TodayViewController.swift in Sources */
,
CD17C5F625D15B4400EE884E
/* TodayViewController.swift in Sources */
,
CD86245E25E646350097F3FB
/* SunUvView.swift in Sources */
,
CD86245E25E646350097F3FB
/* SunUvView.swift in Sources */
,
CEAFF08325DFC67F00DF4EBF
/* Location.swift in Sources */
,
CEAFF08325DFC67F00DF4EBF
/* Location.swift in Sources */
,
CD8E040D25F8F3D2001785B6
/* ForecastTimePeriodCell.swift in Sources */
,
87C171EC25FF79CC00DA3464
/* EnvironmentManager.swift in Sources */
,
87C171EC25FF79CC00DA3464
/* EnvironmentManager.swift in Sources */
,
CD82300725D6A73F00A05501
/* TodayConditionButton.swift in Sources */
,
CD82300725D6A73F00A05501
/* TodayConditionButton.swift in Sources */
,
CDC6126A25E90C8800188DA7
/* GraphLineSettings.swift in Sources */
,
CDC6126A25E90C8800188DA7
/* GraphLineSettings.swift in Sources */
,
...
...
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
View file @
c7d6b24e
No preview for this file type
1Weather/Coordinators/LocationSearchCoordinator.swift
0 → 100644
View file @
c7d6b24e
//
// LocationSearchCoordinator.swift
// 1Weather
//
// Created by Dmitry Stepanets on 30.03.2021.
//
import
UIKit
class
LocationSearchCoordinator
:
Coordinator
{
//Private
private
let
parentViewController
:
UIViewController
//Public
var
childCoordinators
=
[
Coordinator
]()
var
parentCoordinator
:
Coordinator
?
init
(
parentViewController
:
UIViewController
)
{
self
.
parentViewController
=
parentViewController
}
func
start
()
{
let
searchViewController
=
LocationViewController
(
coordinator
:
self
)
let
navigationController
=
UINavigationController
(
rootViewController
:
searchViewController
)
self
.
parentViewController
.
present
(
navigationController
,
animated
:
true
)
}
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
parentCoordinator
?
.
childDidFinish
(
child
:
self
)
}
}
1Weather/Coordinators/TodayCoordinator.swift
View file @
c7d6b24e
...
@@ -21,11 +21,17 @@ class TodayCoordinator:Coordinator {
...
@@ -21,11 +21,17 @@ class TodayCoordinator:Coordinator {
}
}
func
start
()
{
func
start
()
{
let
todayViewController
=
TodayViewController
()
let
todayViewController
=
TodayViewController
(
coordinator
:
self
)
navigationController
.
viewControllers
=
[
todayViewController
]
navigationController
.
viewControllers
=
[
todayViewController
]
tabBarController
?
.
add
(
viewController
:
navigationController
)
tabBarController
?
.
add
(
viewController
:
navigationController
)
}
}
func
openLocationsSearch
()
{
let
searchCoordinator
=
LocationSearchCoordinator
(
parentViewController
:
navigationController
)
searchCoordinator
.
parentCoordinator
=
self
searchCoordinator
.
start
()
}
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
//
//
}
}
...
...
1Weather/Resources/Assets.xcassets/location_arrow.imageset/Contents.json
0 → 100644
View file @
c7d6b24e
{
"images"
:
[
{
"filename"
:
"location_arrow.pdf"
,
"idiom"
:
"universal"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
},
"properties"
:
{
"preserves-vector-representation"
:
true
,
"template-rendering-intent"
:
"template"
}
}
1Weather/Resources/Assets.xcassets/location_arrow.imageset/location_arrow.pdf
0 → 100644
View file @
c7d6b24e
File added
1Weather/Resources/en.lproj/Localizable.strings
View file @
c7d6b24e
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
//General
//General
"general.close" = "close";
"general.close" = "close";
"general.more" = "more";
"general.more" = "more";
"general.search" = "search";
//Forecast
//Forecast
"forecast.sunny" = "Sunny";
"forecast.sunny" = "Sunny";
...
@@ -94,6 +95,11 @@
...
@@ -94,6 +95,11 @@
"tabBar.menu" = "menu";
"tabBar.menu" = "menu";
// Search
// Search
"search.popularCities" = "Popular cities";
"search.title" = "Search location";
"search.savedCities" = "saved cities";
"search.results" = "Results";
"search.currentLocation" = "Use current location";
"search.error.maxLocationWarning" = "To keep your 1Weather running in tip-top shape, please limit the number of locations to %@";
"search.error.maxLocationWarning" = "To keep your 1Weather running in tip-top shape, please limit the number of locations to %@";
"search.error.deleteError" = "Failed to delete location.";
"search.error.deleteError" = "Failed to delete location.";
"search.accessibility.tapToSelectLocation" = "Tap to select this location";
"search.accessibility.tapToSelectLocation" = "Tap to select this location";
...
...
1Weather/UI/View controllers/Locations/LocationViewController.swift
View file @
c7d6b24e
...
@@ -6,41 +6,15 @@
...
@@ -6,41 +6,15 @@
//
//
import
UIKit
import
UIKit
//MARK:- Location Navigation View Controller
class
LocationViewController
:
UINavigationController
{
init
(
closeButtonIsHidden
:
Bool
=
false
,
openedFromOnboarding
:
Bool
=
false
)
{
let
savedCitiesViewController
=
CitiesViewController
(
closeButtonHidden
:
closeButtonIsHidden
,
openedFromOnboarding
:
openedFromOnboarding
)
super
.
init
(
rootViewController
:
savedCitiesViewController
)
self
.
modalPresentationStyle
=
.
fullScreen
//TODO: Dark mode
self
.
navigationBar
.
barTintColor
=
UIColor
(
hex
:
0x17181A
)
// ThemeManager.Colors.primaryBackground
}
override
init
(
nibName
nibNameOrNil
:
String
?,
bundle
nibBundleOrNil
:
Bundle
?)
{
super
.
init
(
nibName
:
nibNameOrNil
,
bundle
:
nibBundleOrNil
)
}
required
init
?(
coder
aDecoder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
override
var
preferredStatusBarStyle
:
UIStatusBarStyle
{
//TODO: Dark mode
return
.
lightContent
}
}
//MARK:- Cities View Controller
//MARK:- Cities View Controller
private
enum
EditButtonStyle
{
private
enum
EditButtonStyle
{
case
edit
case
edit
case
done
case
done
}
}
private
class
Cities
ViewController
:
UIViewController
{
class
Location
ViewController
:
UIViewController
{
//Private
//Private
private
let
openedFromOnboarding
:
Bool
private
let
coordinator
:
LocationSearchCoordinator
private
let
searchBar
=
UISearchBar
()
private
let
searchBar
=
UISearchBar
()
private
let
locationButton
=
SelfSizingButton
(
frame
:
.
zero
)
private
let
locationButton
=
SelfSizingButton
(
frame
:
.
zero
)
private
let
tableView
=
UITableView
()
private
let
tableView
=
UITableView
()
...
@@ -53,10 +27,9 @@ private class CitiesViewController:UIViewController {
...
@@ -53,10 +27,9 @@ private class CitiesViewController:UIViewController {
return
queue
return
queue
}()
}()
init
(
c
loseButtonHidden
:
Bool
=
false
,
openedFromOnboarding
:
Bool
=
false
)
{
init
(
c
oordinator
:
LocationSearchCoordinator
)
{
self
.
openedFromOnboarding
=
openedFromOnboarding
self
.
coordinator
=
coordinator
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
prepareNavBar
(
closeButtonIsHidden
:
closeButtonHidden
)
}
}
required
init
?(
coder
:
NSCoder
)
{
required
init
?(
coder
:
NSCoder
)
{
...
@@ -70,41 +43,33 @@ private class CitiesViewController:UIViewController {
...
@@ -70,41 +43,33 @@ private class CitiesViewController:UIViewController {
edgesForExtendedLayout
=
[]
edgesForExtendedLayout
=
[]
self
.
locationsViewModel
.
delegate
=
self
self
.
locationsViewModel
.
delegate
=
self
prepareController
()
prepareSearchBar
()
prepareSearchBar
()
prepareLocationButton
()
prepareLocationButton
()
prepareTableView
()
prepareTableView
()
prepareEditButton
()
prepareEditButton
()
setupObservers
()
setupObservers
()
updateUI
()
}
}
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
override
func
viewWillAppear
(
_
animated
:
Bool
)
{
super
.
viewWillAppear
(
animated
)
super
.
viewWillAppear
(
animated
)
if
openedFromOnboarding
{
self
.
searchBar
.
becomeFirstResponder
()
}
tableView
.
reloadData
()
tableView
.
reloadData
()
}
}
override
func
viewDidAppear
(
_
animated
:
Bool
)
{
override
func
viewDidAppear
(
_
animated
:
Bool
)
{
super
.
viewDidAppear
(
animated
)
super
.
viewDidAppear
(
animated
)
if
openedFromOnboarding
{
#warning("TODO Flurry analytics")
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_SEEN
)
// if openedFromOnboarding {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_SEEN)
// }
}
}
override
func
viewWillLayoutSubviews
()
{
override
func
traitCollectionDidChange
(
_
previousTraitCollection
:
UITraitCollection
?)
{
super
.
viewWillLayoutSubviews
()
super
.
traitCollectionDidChange
(
previousTraitCollection
)
updateUI
()
//Update navigation title view constraints
guard
let
containerView
=
self
.
navigationItem
.
titleView
?
.
superview
else
{
return
}
self
.
navigationItem
.
titleView
?
.
snp
.
remakeConstraints
({
(
make
)
in
make
.
left
.
equalTo
(
containerView
)
.
inset
(
24
)
.
priority
(
.
medium
)
make
.
top
.
equalTo
(
containerView
)
.
priority
(
.
medium
)
make
.
right
.
equalTo
(
containerView
)
.
priority
(
.
medium
)
make
.
bottom
.
equalTo
(
containerView
)
.
priority
(
.
medium
)
})
}
}
private
func
updateEditButton
(
style
:
EditButtonStyle
)
{
private
func
updateEditButton
(
style
:
EditButtonStyle
)
{
switch
style
{
switch
style
{
case
.
edit
:
case
.
edit
:
...
@@ -124,14 +89,31 @@ private class CitiesViewController:UIViewController {
...
@@ -124,14 +89,31 @@ private class CitiesViewController:UIViewController {
self
.
navigationController
?
.
dismiss
(
animated
:
true
)
self
.
navigationController
?
.
dismiss
(
animated
:
true
)
}
}
private
func
updateUI
()
{
view
.
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
tableView
.
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
let
searchBarTextField
=
searchBar
.
value
(
forKey
:
"searchField"
)
as?
UITextField
switch
view
.
interfaceStyle
{
case
.
light
:
searchBarTextField
?
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
searchBarTextField
?
.
leftView
?
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
case
.
dark
:
searchBarTextField
?
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
searchBarTextField
?
.
leftView
?
.
tintColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
}
}
@objc
private
func
handleCloseButton
()
{
@objc
private
func
handleCloseButton
()
{
close
()
close
()
}
}
@objc
private
func
handleLocationButton
()
{
@objc
private
func
handleLocationButton
()
{
if
openedFromOnboarding
{
#warning("TODO Flurry analytics")
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_GPS
)
// if openedFromOnboarding {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_GPS)
// }
locationsViewModel
.
useCurrentLocation
(
requestedBy
:
self
)
locationsViewModel
.
useCurrentLocation
(
requestedBy
:
self
)
}
}
...
@@ -142,33 +124,20 @@ private class CitiesViewController:UIViewController {
...
@@ -142,33 +124,20 @@ private class CitiesViewController:UIViewController {
}
}
//MARK:- Saved cities prepare
//MARK:- Saved cities prepare
private
extension
CitiesViewController
{
private
extension
LocationViewController
{
func
prepareNavBar
(
closeButtonIsHidden
:
Bool
)
{
func
prepareController
()
{
self
.
navigationController
?
.
view
.
backgroundColor
=
.
white
navigationItem
.
title
=
"search.title"
.
localized
()
.
capitalized
let
closeButton
=
UIBarButtonItem
(
title
:
"general.close"
.
localized
()
.
capitalized
,
//Title
style
:
.
done
,
let
titleLabel
=
UILabel
()
target
:
self
,
titleLabel
.
textAlignment
=
.
left
action
:
#selector(
handleCloseButton
)
)
titleLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
24
)
navigationItem
.
leftBarButtonItem
=
closeButton
titleLabel
.
text
=
"Select Location"
.
localized
titleLabel
.
translatesAutoresizingMaskIntoConstraints
=
false
titleLabel
.
textColor
=
ThemeManager
.
Colors
.
primaryTextColor
navigationItem
.
titleView
=
titleLabel
if
!
closeButtonIsHidden
{
//Close button
let
closeButton
=
UIBarButtonItem
(
image
:
UIImage
(
named
:
"close_cross"
),
style
:
.
plain
,
target
:
self
,
action
:
#selector(
handleCloseButton
)
)
closeButton
.
tintColor
=
ThemeManager
.
Colors
.
primaryTextColor
self
.
navigationItem
.
rightBarButtonItems
=
[
closeButton
]
}
}
}
func
prepareSearchBar
()
{
func
prepareSearchBar
()
{
let
searchBarTextField
=
searchBar
.
value
(
forKey
:
"searchField"
)
as?
UITextField
let
searchBarTextField
=
searchBar
.
value
(
forKey
:
"searchField"
)
as?
UITextField
searchBarTextField
?
.
textColor
=
ThemeManager
.
Colors
.
primaryTextColor
searchBarTextField
?
.
leftView
?
.
tintColor
=
ThemeManager
.
Colors
.
searchBarTint
searchBar
.
searchBarStyle
=
.
minimal
searchBar
.
searchBarStyle
=
.
minimal
searchBar
.
placeholder
=
"
Search"
.
loc
alized
searchBar
.
placeholder
=
"
general.search"
.
localized
()
.
capit
alized
searchBar
.
delegate
=
self
searchBar
.
delegate
=
self
view
.
addSubview
(
searchBar
)
view
.
addSubview
(
searchBar
)
searchBar
.
snp
.
makeConstraints
{
(
make
)
in
searchBar
.
snp
.
makeConstraints
{
(
make
)
in
...
@@ -181,11 +150,11 @@ private extension CitiesViewController {
...
@@ -181,11 +150,11 @@ private extension CitiesViewController {
func
prepareLocationButton
()
{
func
prepareLocationButton
()
{
locationButton
.
tintColor
=
ThemeManager
.
Colors
.
locationBlue
locationButton
.
tintColor
=
ThemeManager
.
Colors
.
locationBlue
locationButton
.
setImage
(
UIImage
(
named
:
"location_arrow"
),
for
:
.
normal
)
locationButton
.
setImage
(
UIImage
(
named
:
"location_arrow"
),
for
:
.
normal
)
locationButton
.
setTitle
(
"
Use Current Location"
.
localized
,
for
:
.
normal
)
locationButton
.
setTitle
(
"
search.currentLocation"
.
localized
()
,
for
:
.
normal
)
locationButton
.
setTitleColor
(
ThemeManager
.
Colors
.
locationBlue
,
for
:
.
normal
)
locationButton
.
setTitleColor
(
ThemeManager
.
Colors
.
locationBlue
,
for
:
.
normal
)
locationButton
.
setTitleColor
(
ThemeManager
.
Colors
.
locationBlue
.
highlighted
,
for
:
.
highlighted
)
locationButton
.
setTitleColor
(
ThemeManager
.
Colors
.
locationBlue
.
highlighted
,
for
:
.
highlighted
)
locationButton
.
addTarget
(
self
,
action
:
#selector(
handleLocationButton
)
,
for
:
.
touchUpInside
)
locationButton
.
addTarget
(
self
,
action
:
#selector(
handleLocationButton
)
,
for
:
.
touchUpInside
)
locationButton
.
titleLabel
?
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
1
8
)
locationButton
.
titleLabel
?
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
1
6
)
locationButton
.
titleEdgeInsets
=
.
init
(
top
:
0
,
left
:
26
,
bottom
:
0
,
right
:
0
)
locationButton
.
titleEdgeInsets
=
.
init
(
top
:
0
,
left
:
26
,
bottom
:
0
,
right
:
0
)
locationButton
.
sizeToFit
()
locationButton
.
sizeToFit
()
...
@@ -244,7 +213,7 @@ private extension CitiesViewController {
...
@@ -244,7 +213,7 @@ private extension CitiesViewController {
}
}
//MARK:- LocationsViewModel Delegate
//MARK:- LocationsViewModel Delegate
extension
Cities
ViewController
:
LocationsViewModelDelegate
{
extension
Location
ViewController
:
LocationsViewModelDelegate
{
func
viewModelDidChange
(
model
:
LocationsViewModel
)
{
func
viewModelDidChange
(
model
:
LocationsViewModel
)
{
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
self
.
tableView
.
reloadData
()
self
.
tableView
.
reloadData
()
...
@@ -273,7 +242,7 @@ extension CitiesViewController: LocationsViewModelDelegate {
...
@@ -273,7 +242,7 @@ extension CitiesViewController: LocationsViewModelDelegate {
}
}
//MARK: UItableView Data Source
//MARK: UItableView Data Source
extension
Cities
ViewController
:
UITableViewDataSource
{
extension
Location
ViewController
:
UITableViewDataSource
{
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
return
locationsViewModel
.
cities
.
count
return
locationsViewModel
.
cities
.
count
}
}
...
@@ -290,17 +259,18 @@ extension CitiesViewController: UITableViewDataSource {
...
@@ -290,17 +259,18 @@ extension CitiesViewController: UITableViewDataSource {
let
displayModeOnCreation
=
self
.
locationsViewModel
.
displayMode
let
displayModeOnCreation
=
self
.
locationsViewModel
.
displayMode
cell
.
onAdd
=
{
[
weak
self
]
in
cell
.
onAdd
=
{
[
weak
self
]
in
guard
let
strongSelf
=
self
else
{
return
}
guard
let
self
=
self
else
{
return
}
strongSelf
.
locationsViewModel
.
add
(
city
:
strongSelf
.
locationsViewModel
.
cities
[
indexPath
.
row
])
self
.
locationsViewModel
.
add
(
city
:
self
.
locationsViewModel
.
cities
[
indexPath
.
row
])
if
strongSelf
.
openedFromOnboarding
{
#warning("TODO Flurry analytics")
if
displayModeOnCreation
==
.
popularCities
{
// if strongSelf.openedFromOnboarding {
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_POPULAR
)
// if displayModeOnCreation == .popularCities {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_POPULAR)
else
{
// }
// else {
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_ADD
)
//
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_ADD)
}
// }
// }
}
}
cell
.
onSelect
=
{[
weak
self
]
in
cell
.
onSelect
=
{[
weak
self
]
in
...
@@ -312,19 +282,26 @@ extension CitiesViewController: UITableViewDataSource {
...
@@ -312,19 +282,26 @@ extension CitiesViewController: UITableViewDataSource {
}
}
//MARK: UITableView Delegate
//MARK: UITableView Delegate
extension
Cities
ViewController
:
UITableViewDelegate
{
extension
Location
ViewController
:
UITableViewDelegate
{
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
let
container
=
UIView
()
let
container
=
UIView
()
container
.
backgroundColor
=
ThemeManager
.
Colors
.
primaryBackground
container
.
backgroundColor
=
tableView
.
backgroundColor
let
titleLabel
=
UILabel
()
let
titleLabel
=
UILabel
()
titleLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
24
)
titleLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
24
)
titleLabel
.
textColor
=
ThemeManager
.
Colors
.
primaryTextColor
switch
view
.
interfaceStyle
{
case
.
light
:
titleLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
case
.
dark
:
titleLabel
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
}
container
.
addSubview
(
titleLabel
)
container
.
addSubview
(
titleLabel
)
switch
self
.
locationsViewModel
.
displayMode
{
switch
self
.
locationsViewModel
.
displayMode
{
case
.
savedCities
:
case
.
savedCities
:
titleLabel
.
text
=
"
Saved Cities"
.
localized
+
"
(
\(
self
.
locationsViewModel
.
cities
.
count
)
)"
titleLabel
.
text
=
"
search.savedCities"
.
localized
()
.
capitalized
+
"
(
\(
self
.
locationsViewModel
.
cities
.
count
)
)"
//Add Edit button
//Add Edit button
container
.
addSubview
(
editButton
)
container
.
addSubview
(
editButton
)
...
@@ -333,9 +310,9 @@ extension CitiesViewController: UITableViewDelegate {
...
@@ -333,9 +310,9 @@ extension CitiesViewController: UITableViewDelegate {
make
.
bottom
.
equalTo
(
titleLabel
)
make
.
bottom
.
equalTo
(
titleLabel
)
}
}
case
.
popularCities
:
case
.
popularCities
:
titleLabel
.
text
=
"
\(
locationsViewModel
.
cities
.
count
)
Popular cities"
.
localized
titleLabel
.
text
=
"
\(
locationsViewModel
.
cities
.
count
)
"
+
"search.popularCities"
.
localized
()
case
.
searchResults
:
case
.
searchResults
:
titleLabel
.
text
=
"
Results"
.
loc
alized
+
"(
\(
self
.
locationsViewModel
.
cities
.
count
)
)"
titleLabel
.
text
=
"
search.results"
.
localized
()
.
capit
alized
+
"(
\(
self
.
locationsViewModel
.
cities
.
count
)
)"
}
}
titleLabel
.
snp
.
makeConstraints
{
(
make
)
in
titleLabel
.
snp
.
makeConstraints
{
(
make
)
in
...
@@ -433,14 +410,16 @@ extension CitiesViewController: UITableViewDelegate {
...
@@ -433,14 +410,16 @@ extension CitiesViewController: UITableViewDelegate {
locationsViewModel
.
select
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
locationsViewModel
.
select
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
case
.
searchResults
:
case
.
searchResults
:
locationsViewModel
.
add
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
locationsViewModel
.
add
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
if
openedFromOnboarding
{
#warning("TODO Flurry analytics")
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_ADD
)
// if openedFromOnboarding {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_ADD)
// }
case
.
popularCities
:
case
.
popularCities
:
locationsViewModel
.
add
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
locationsViewModel
.
add
(
city
:
locationsViewModel
.
cities
[
indexPath
.
row
])
if
openedFromOnboarding
{
#warning("TODO Flurry analytics")
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_POPULAR
)
// if openedFromOnboarding {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_POPULAR)
// }
}
}
self
.
close
()
self
.
close
()
//TODO: should be done from ViewModel?
//TODO: should be done from ViewModel?
...
@@ -448,14 +427,15 @@ extension CitiesViewController: UITableViewDelegate {
...
@@ -448,14 +427,15 @@ extension CitiesViewController: UITableViewDelegate {
}
}
//MARK:- UISearchBar Delegate
//MARK:- UISearchBar Delegate
extension
Cities
ViewController
:
UISearchBarDelegate
{
extension
Location
ViewController
:
UISearchBarDelegate
{
func
searchBarTextDidBeginEditing
(
_
searchBar
:
UISearchBar
)
{
func
searchBarTextDidBeginEditing
(
_
searchBar
:
UISearchBar
)
{
searchBar
.
setShowsCancelButton
(
true
,
animated
:
true
)
searchBar
.
setShowsCancelButton
(
true
,
animated
:
true
)
self
.
locationsViewModel
.
displayMode
=
.
popularCities
self
.
locationsViewModel
.
displayMode
=
.
popularCities
self
.
locationsViewModel
.
fetchPopularCities
()
self
.
locationsViewModel
.
fetchPopularCities
()
if
openedFromOnboarding
{
#warning("TODO Flurry analytics")
analytics
(
log
:
.
ANALYTICS_FTUE_SEARCH_TAP
)
// if openedFromOnboarding {
}
// analytics(log: .ANALYTICS_FTUE_SEARCH_TAP)
// }
}
}
func
searchBar
(
_
searchBar
:
UISearchBar
,
textDidChange
searchText
:
String
)
{
func
searchBar
(
_
searchBar
:
UISearchBar
,
textDidChange
searchText
:
String
)
{
...
...
1Weather/UI/View controllers/Today/Cells/TodayForecastTimePeriodCell.swift
View file @
c7d6b24e
...
@@ -35,7 +35,7 @@ class TodayForecastTimePeriodCell: UITableViewCell {
...
@@ -35,7 +35,7 @@ class TodayForecastTimePeriodCell: UITableViewCell {
public
func
configure
(
with
location
:
Location
)
{
public
func
configure
(
with
location
:
Location
)
{
self
.
forecastTimePeriodView
.
set
(
daily
:
location
.
daily
,
hourly
:
location
.
hourly
)
self
.
forecastTimePeriodView
.
set
(
daily
:
location
.
daily
,
hourly
:
location
.
hourly
)
if
graphIsDrawn
==
false
{
if
graphIsDrawn
==
false
{
self
.
handleSegmentDidChange
()
self
.
handleSegmentDidChange
()
self
.
graphIsDrawn
=
true
self
.
graphIsDrawn
=
true
}
}
...
...
1Weather/UI/View controllers/Today/TodayViewController.swift
View file @
c7d6b24e
...
@@ -10,6 +10,7 @@ import CoreLocation
...
@@ -10,6 +10,7 @@ import CoreLocation
class
TodayViewController
:
UIViewController
{
class
TodayViewController
:
UIViewController
{
//Private
//Private
private
let
coordinator
:
TodayCoordinator
private
let
viewModel
=
TodayViewModel
()
private
let
viewModel
=
TodayViewModel
()
private
let
todayCellFactory
:
TodayCellFactory
private
let
todayCellFactory
:
TodayCellFactory
private
let
cityButton
=
NavigationCityButton
()
private
let
cityButton
=
NavigationCityButton
()
...
@@ -22,7 +23,8 @@ class TodayViewController: UIViewController {
...
@@ -22,7 +23,8 @@ class TodayViewController: UIViewController {
}
}
}
}
init
()
{
init
(
coordinator
:
TodayCoordinator
)
{
self
.
coordinator
=
coordinator
self
.
todayCellFactory
=
TodayCellFactory
(
viewModel
:
viewModel
)
self
.
todayCellFactory
=
TodayCellFactory
(
viewModel
:
viewModel
)
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
}
}
...
@@ -51,8 +53,7 @@ class TodayViewController: UIViewController {
...
@@ -51,8 +53,7 @@ class TodayViewController: UIViewController {
}
}
@objc
private
func
handleCityButton
()
{
@objc
private
func
handleCityButton
()
{
let
locationViewController
=
LocationViewController
(
closeButtonIsHidden
:
false
)
self
.
coordinator
.
openLocationsSearch
()
present
(
locationViewController
,
animated
:
true
)
}
}
@objc
private
func
handleNotificationButton
()
{
@objc
private
func
handleNotificationButton
()
{
...
@@ -71,7 +72,7 @@ private extension TodayViewController {
...
@@ -71,7 +72,7 @@ private extension TodayViewController {
func
prepareNavigationBar
()
{
func
prepareNavigationBar
()
{
//City button
//City button
cityButton
.
isHidden
=
tru
e
cityButton
.
isHidden
=
fals
e
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
)
...
...
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