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
b27b7c66
Commit
b27b7c66
authored
Mar 27, 2021
by
Dmitriy Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added SettingsDetailsViewController UI
parent
325b21e7
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
620 additions
and
55 deletions
+620
-55
1Weather.xcodeproj/project.pbxproj
+24
-0
1Weather.xcodeproj/xcuserdata/dstepanets.xcuserdatad/xcschemes/xcschememanagement.plist
+1
-1
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
+0
-0
1Weather/Coordinators/SettingsCoordinator.swift
+10
-2
1Weather/Coordinators/SettingsDetailsCoordinator.swift
+34
-0
1Weather/Extensions/Dimension+Name.swift
+21
-0
1Weather/Extensions/Measurement+String.swift
+11
-15
1Weather/Extensions/UIView+InterfaceStyle.swift
+11
-4
1Weather/Model/HelperTypes.swift
+8
-8
1Weather/Model/Settings.swift
+5
-0
1Weather/Resources/Assets.xcassets/checkmark.imageset/Contents.json
+16
-0
1Weather/Resources/Assets.xcassets/checkmark.imageset/checkmark.pdf
+0
-0
1Weather/Resources/Assets.xcassets/checkmark_selected.imageset/Contents.json
+15
-0
1Weather/Resources/Assets.xcassets/checkmark_selected.imageset/checkmark_selected.pdf
+0
-0
1Weather/Resources/Assets.xcassets/checkmark_unselected.imageset/Contents.json
+15
-0
1Weather/Resources/Assets.xcassets/checkmark_unselected.imageset/checkmark_unselected.pdf
+0
-0
1Weather/Resources/en.lproj/Localizable.strings
+4
-0
1Weather/UI/Helpers/ForecastTimePeriod/ForecastTimePeriodView.swift
+3
-3
1Weather/UI/View controllers/Settings/Cells/SettingsCellFactory.swift
+84
-8
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCell.swift
+100
-0
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCellFactory.swift
+84
-0
1Weather/UI/View controllers/Settings/Cells/SettingsThemeCell.swift
+5
-0
1Weather/UI/View controllers/Settings/SettingsDetailsViewController.swift
+73
-0
1Weather/UI/View controllers/Settings/SettingsViewController.swift
+38
-10
1Weather/ViewModels/SettingsDetailsViewModel.swift
+52
-0
1Weather/ViewModels/SettingsViewModel.swift
+3
-1
Pods/Pods.xcodeproj/xcuserdata/dstepanets.xcuserdatad/xcschemes/xcschememanagement.plist
+3
-3
No files found.
1Weather.xcodeproj/project.pbxproj
View file @
b27b7c66
...
@@ -74,6 +74,12 @@
...
@@ -74,6 +74,12 @@
CD86246525E66E8A0097F3FB
/* PrecipitationCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246425E66E8A0097F3FB
/* PrecipitationCell.swift */
;
};
CD86246525E66E8A0097F3FB
/* PrecipitationCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246425E66E8A0097F3FB
/* PrecipitationCell.swift */
;
};
CD86246925E672A20097F3FB
/* PrecipButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246825E672A20097F3FB
/* PrecipButton.swift */
;
};
CD86246925E672A20097F3FB
/* PrecipButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246825E672A20097F3FB
/* PrecipButton.swift */
;
};
CD86246C25E6826A0097F3FB
/* InnerShadowLayer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246B25E6826A0097F3FB
/* InnerShadowLayer.swift */
;
};
CD86246C25E6826A0097F3FB
/* InnerShadowLayer.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86246B25E6826A0097F3FB
/* InnerShadowLayer.swift */
;
};
CD866A62260F596B00E96A5C
/* Dimension+Name.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A61260F596B00E96A5C
/* Dimension+Name.swift */
;
};
CD866A65260F642600E96A5C
/* SettingsDetailsViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A64260F642600E96A5C
/* SettingsDetailsViewController.swift */
;
};
CD866A6C260F676400E96A5C
/* SettingsDetailsCellFactory.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A6B260F676400E96A5C
/* SettingsDetailsCellFactory.swift */
;
};
CD866A6F260F67F200E96A5C
/* SettingsDetailsViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A6E260F67F200E96A5C
/* SettingsDetailsViewModel.swift */
;
};
CD866A72260F6A5300E96A5C
/* SettingsDetailsCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A71260F6A5300E96A5C
/* SettingsDetailsCell.swift */
;
};
CD866A76260F77C500E96A5C
/* SettingsDetailsCoordinator.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD866A75260F77C500E96A5C
/* SettingsDetailsCoordinator.swift */
;
};
CD86C22225F0DCCB00F38A16
/* PrecipitationView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86C22125F0DCCB00F38A16
/* PrecipitationView.swift */
;
};
CD86C22225F0DCCB00F38A16
/* PrecipitationView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD86C22125F0DCCB00F38A16
/* PrecipitationView.swift */
;
};
CD8E041225F8F775001785B6
/* ForecastViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD8E041125F8F775001785B6
/* ForecastViewModel.swift */
;
};
CD8E041225F8F775001785B6
/* ForecastViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD8E041125F8F775001785B6
/* ForecastViewModel.swift */
;
};
CD8E041625F8F91B001785B6
/* ForecastCellFactory.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD8E041525F8F91B001785B6
/* ForecastCellFactory.swift */
;
};
CD8E041625F8F91B001785B6
/* ForecastCellFactory.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CD8E041525F8F91B001785B6
/* ForecastCellFactory.swift */
;
};
...
@@ -196,6 +202,12 @@
...
@@ -196,6 +202,12 @@
CD86246425E66E8A0097F3FB
/* PrecipitationCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipitationCell.swift
;
sourceTree
=
"<group>"
;
};
CD86246425E66E8A0097F3FB
/* PrecipitationCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipitationCell.swift
;
sourceTree
=
"<group>"
;
};
CD86246825E672A20097F3FB
/* PrecipButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipButton.swift
;
sourceTree
=
"<group>"
;
};
CD86246825E672A20097F3FB
/* PrecipButton.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipButton.swift
;
sourceTree
=
"<group>"
;
};
CD86246B25E6826A0097F3FB
/* InnerShadowLayer.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
InnerShadowLayer.swift
;
sourceTree
=
"<group>"
;
};
CD86246B25E6826A0097F3FB
/* InnerShadowLayer.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
InnerShadowLayer.swift
;
sourceTree
=
"<group>"
;
};
CD866A61260F596B00E96A5C
/* Dimension+Name.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"Dimension+Name.swift"
;
sourceTree
=
"<group>"
;
};
CD866A64260F642600E96A5C
/* SettingsDetailsViewController.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsDetailsViewController.swift
;
sourceTree
=
"<group>"
;
};
CD866A6B260F676400E96A5C
/* SettingsDetailsCellFactory.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsDetailsCellFactory.swift
;
sourceTree
=
"<group>"
;
};
CD866A6E260F67F200E96A5C
/* SettingsDetailsViewModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsDetailsViewModel.swift
;
sourceTree
=
"<group>"
;
};
CD866A71260F6A5300E96A5C
/* SettingsDetailsCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsDetailsCell.swift
;
sourceTree
=
"<group>"
;
};
CD866A75260F77C500E96A5C
/* SettingsDetailsCoordinator.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SettingsDetailsCoordinator.swift
;
sourceTree
=
"<group>"
;
};
CD86C22125F0DCCB00F38A16
/* PrecipitationView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipitationView.swift
;
sourceTree
=
"<group>"
;
};
CD86C22125F0DCCB00F38A16
/* PrecipitationView.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PrecipitationView.swift
;
sourceTree
=
"<group>"
;
};
CD8E041125F8F775001785B6
/* ForecastViewModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastViewModel.swift
;
sourceTree
=
"<group>"
;
};
CD8E041125F8F775001785B6
/* ForecastViewModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastViewModel.swift
;
sourceTree
=
"<group>"
;
};
CD8E041525F8F91B001785B6
/* ForecastCellFactory.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastCellFactory.swift
;
sourceTree
=
"<group>"
;
};
CD8E041525F8F91B001785B6
/* ForecastCellFactory.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ForecastCellFactory.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -335,6 +347,7 @@
...
@@ -335,6 +347,7 @@
CD593BC826089FC100C93428
/* UITableView+HeaderSize.swift */
,
CD593BC826089FC100C93428
/* UITableView+HeaderSize.swift */
,
CD593BDB2608CDF100C93428
/* Date+Now.swift */
,
CD593BDB2608CDF100C93428
/* Date+Now.swift */
,
CD2B213F260A366B00AB918A
/* UIView+InterfaceStyle.swift */
,
CD2B213F260A366B00AB918A
/* UIView+InterfaceStyle.swift */
,
CD866A61260F596B00E96A5C
/* Dimension+Name.swift */
,
);
);
path
=
Extensions
;
path
=
Extensions
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -365,6 +378,7 @@
...
@@ -365,6 +378,7 @@
CDE18DCC25D1666700C80ED9
/* ForecastCoordinator.swift */
,
CDE18DCC25D1666700C80ED9
/* ForecastCoordinator.swift */
,
CD32CE0A260C744A00235081
/* MenuCoordinator.swift */
,
CD32CE0A260C744A00235081
/* MenuCoordinator.swift */
,
CD37D3F2260DF4FB002669D6
/* SettingsCoordinator.swift */
,
CD37D3F2260DF4FB002669D6
/* SettingsCoordinator.swift */
,
CD866A75260F77C500E96A5C
/* SettingsDetailsCoordinator.swift */
,
);
);
path
=
Coordinators
;
path
=
Coordinators
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -430,6 +444,7 @@
...
@@ -430,6 +444,7 @@
children
=
(
children
=
(
CD37D3F8260DF6F6002669D6
/* Cells */
,
CD37D3F8260DF6F6002669D6
/* Cells */
,
CD37D3EE260DF4E6002669D6
/* SettingsViewController.swift */
,
CD37D3EE260DF4E6002669D6
/* SettingsViewController.swift */
,
CD866A64260F642600E96A5C
/* SettingsDetailsViewController.swift */
,
);
);
path
=
Settings
;
path
=
Settings
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -440,6 +455,8 @@
...
@@ -440,6 +455,8 @@
CD37D3FD260DF726002669D6
/* SettingsCellFactory.swift */
,
CD37D3FD260DF726002669D6
/* SettingsCellFactory.swift */
,
CD37D3F9260DF714002669D6
/* SettingsThemeCell.swift */
,
CD37D3F9260DF714002669D6
/* SettingsThemeCell.swift */
,
CD37D400260DF744002669D6
/* SettingsCell.swift */
,
CD37D400260DF744002669D6
/* SettingsCell.swift */
,
CD866A6B260F676400E96A5C
/* SettingsDetailsCellFactory.swift */
,
CD866A71260F6A5300E96A5C
/* SettingsDetailsCell.swift */
,
);
);
path
=
Cells
;
path
=
Cells
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -452,6 +469,7 @@
...
@@ -452,6 +469,7 @@
CD647D0525ED08050034578B
/* ViewModelProtocol.swift */
,
CD647D0525ED08050034578B
/* ViewModelProtocol.swift */
,
CD32CE07260C743B00235081
/* MenuViewModel.swift */
,
CD32CE07260C743B00235081
/* MenuViewModel.swift */
,
CD37D3F5260DF5BA002669D6
/* SettingsViewModel.swift */
,
CD37D3F5260DF5BA002669D6
/* SettingsViewModel.swift */
,
CD866A6E260F67F200E96A5C
/* SettingsDetailsViewModel.swift */
,
);
);
path
=
ViewModels
;
path
=
ViewModels
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -832,13 +850,17 @@
...
@@ -832,13 +850,17 @@
CD82300325D69DE400A05501
/* CityConditionsCell.swift in Sources */
,
CD82300325D69DE400A05501
/* CityConditionsCell.swift in Sources */
,
CEC526FD25E795F700DA58A5
/* WdtWeatherSource.swift in Sources */
,
CEC526FD25E795F700DA58A5
/* WdtWeatherSource.swift in Sources */
,
CD32CE08260C743B00235081
/* MenuViewModel.swift in Sources */
,
CD32CE08260C743B00235081
/* MenuViewModel.swift in Sources */
,
CD866A76260F77C500E96A5C
/* SettingsDetailsCoordinator.swift in Sources */
,
CEAFF09225DFC71D00DF4EBF
/* HelperTypes.swift in Sources */
,
CEAFF09225DFC71D00DF4EBF
/* HelperTypes.swift in Sources */
,
CD866A62260F596B00E96A5C
/* Dimension+Name.swift in Sources */
,
CDE2BF222609D4250085C930
/* ForecastWindSpeedCell.swift in Sources */
,
CDE2BF222609D4250085C930
/* ForecastWindSpeedCell.swift in Sources */
,
CD866A6C260F676400E96A5C
/* SettingsDetailsCellFactory.swift in Sources */
,
CDA5543025EFA13F00A2E08C
/* Measurement+String.swift in Sources */
,
CDA5543025EFA13F00A2E08C
/* Measurement+String.swift in Sources */
,
CE9D181925ECB9A70028D9D7
/* Logger.swift in Sources */
,
CE9D181925ECB9A70028D9D7
/* Logger.swift in Sources */
,
CE578FD325F7E89400E8B85D
/* DayTimeWeather.swift in Sources */
,
CE578FD325F7E89400E8B85D
/* DayTimeWeather.swift in Sources */
,
CD593BCC2608A4F200C93428
/* ForecastDailyCell.swift in Sources */
,
CD593BCC2608A4F200C93428
/* ForecastDailyCell.swift in Sources */
,
CEAFF08925DFC6B200DF4EBF
/* CurrentWeather.swift in Sources */
,
CEAFF08925DFC6B200DF4EBF
/* CurrentWeather.swift in Sources */
,
CD866A72260F6A5300E96A5C
/* SettingsDetailsCell.swift in Sources */
,
CEC5270325E7BB4000DA58A5
/* WdtSurfaceObservation.swift in Sources */
,
CEC5270325E7BB4000DA58A5
/* WdtSurfaceObservation.swift in Sources */
,
CEAFF08C25DFC6BD00DF4EBF
/* DailyWeather.swift in Sources */
,
CEAFF08C25DFC6BD00DF4EBF
/* DailyWeather.swift in Sources */
,
CEDE4F0B25EFA3A7007457E9
/* UpdatableModelObject.swift in Sources */
,
CEDE4F0B25EFA3A7007457E9
/* UpdatableModelObject.swift in Sources */
,
...
@@ -860,6 +882,7 @@
...
@@ -860,6 +882,7 @@
CD9B6B1425DBCDE2001D9B80
/* GraphView.swift in Sources */
,
CD9B6B1425DBCDE2001D9B80
/* GraphView.swift in Sources */
,
CD39F2EE25DE858D009FE398
/* NotificationName+Localization.swift in Sources */
,
CD39F2EE25DE858D009FE398
/* NotificationName+Localization.swift in Sources */
,
CEAFF08F25DFC6ED00DF4EBF
/* HourlyWeather.swift in Sources */
,
CEAFF08F25DFC6ED00DF4EBF
/* HourlyWeather.swift in Sources */
,
CD866A6F260F67F200E96A5C
/* SettingsDetailsViewModel.swift in Sources */
,
CD71709025FA317700A63C27
/* ForecastTimePeriodView.swift in Sources */
,
CD71709025FA317700A63C27
/* ForecastTimePeriodView.swift in Sources */
,
CD35DFD426034BCD00F2138F
/* UIStackView+RemoveAll.swift in Sources */
,
CD35DFD426034BCD00F2138F
/* UIStackView+RemoveAll.swift in Sources */
,
CD37D3E5260CB05C002669D6
/* MenuFooterView.swift in Sources */
,
CD37D3E5260CB05C002669D6
/* MenuFooterView.swift in Sources */
,
...
@@ -901,6 +924,7 @@
...
@@ -901,6 +924,7 @@
CD35DFCC260341B000F2138F
/* Calendar+TimeZone.swift in Sources */
,
CD35DFCC260341B000F2138F
/* Calendar+TimeZone.swift in Sources */
,
CD9B6B1125DBC723001D9B80
/* CubicCurveAlgorithm.swift in Sources */
,
CD9B6B1125DBC723001D9B80
/* CubicCurveAlgorithm.swift in Sources */
,
CEC5270025E7BACB00DA58A5
/* WdtLocation.swift in Sources */
,
CEC5270025E7BACB00DA58A5
/* WdtLocation.swift in Sources */
,
CD866A65260F642600E96A5C
/* SettingsDetailsViewController.swift in Sources */
,
CD647D0225ED07D60034578B
/* TodayViewModel.swift in Sources */
,
CD647D0225ED07D60034578B
/* TodayViewModel.swift in Sources */
,
CD593BD32608BC3F00C93428
/* ForecastDayCell.swift in Sources */
,
CD593BD32608BC3F00C93428
/* ForecastDayCell.swift in Sources */
,
CD15DB4225DA806C00024727
/* CityForecastTimePeriodCell.swift in Sources */
,
CD15DB4225DA806C00024727
/* CityForecastTimePeriodCell.swift in Sources */
,
...
...
1Weather.xcodeproj/xcuserdata/dstepanets.xcuserdatad/xcschemes/xcschememanagement.plist
View file @
b27b7c66
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
<
k
e
y
>
1Weather.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
k
e
y
>
1Weather.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
int
e
g
e
r
>
6
<
/int
e
g
e
r
>
<
int
e
g
e
r
>
3
<
/int
e
g
e
r
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
k
e
y
>
PG
(
Playground
)
1.xcscheme
<
/k
e
y
>
<
k
e
y
>
PG
(
Playground
)
1.xcscheme
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
...
...
1Weather.xcworkspace/xcuserdata/dstepanets.xcuserdatad/UserInterfaceState.xcuserstate
View file @
b27b7c66
No preview for this file type
1Weather/Coordinators/SettingsCoordinator.swift
View file @
b27b7c66
...
@@ -10,6 +10,7 @@ import UIKit
...
@@ -10,6 +10,7 @@ import UIKit
class
SettingsCoordinator
:
Coordinator
{
class
SettingsCoordinator
:
Coordinator
{
//Private
//Private
private
let
settingsViewModel
=
SettingsViewModel
()
private
let
settingsViewModel
=
SettingsViewModel
()
private
let
navVC
=
UINavigationController
()
private
var
parentViewController
:
UIViewController
?
private
var
parentViewController
:
UIViewController
?
//Public
//Public
...
@@ -23,11 +24,18 @@ class SettingsCoordinator: Coordinator {
...
@@ -23,11 +24,18 @@ class SettingsCoordinator: Coordinator {
func
start
()
{
func
start
()
{
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
let
settingsViewController
=
SettingsViewController
(
coordinator
:
self
,
settingsViewModel
:
self
.
settingsViewModel
)
let
settingsViewController
=
SettingsViewController
(
coordinator
:
self
,
settingsViewModel
:
self
.
settingsViewModel
)
let
navVC
=
UINavigationController
(
rootViewController
:
settingsViewController
)
self
.
navVC
.
setViewControllers
([
settingsViewController
],
animated
:
false
)
self
.
parentViewController
?
.
present
(
navVC
,
animated
:
true
)
self
.
parentViewController
?
.
present
(
self
.
navVC
,
animated
:
true
)
}
}
}
}
func
openDetailsViewController
(
rowType
:
SettingsRow
)
{
let
detailsCoordinator
=
SettingsDetailsCoordinator
(
navigationController
:
self
.
navVC
,
settingsRow
:
rowType
)
detailsCoordinator
.
parentCoordinator
=
self
childCoordinators
.
append
(
detailsCoordinator
)
detailsCoordinator
.
start
()
}
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
}
}
...
...
1Weather/Coordinators/SettingsDetailsCoordinator.swift
0 → 100644
View file @
b27b7c66
//
// SettingsDetailsCoordinator.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
class
SettingsDetailsCoordinator
:
Coordinator
{
//Private
private
let
navigationController
:
UINavigationController
private
let
settingsRow
:
SettingsRow
//Public
var
childCoordinators
=
[
Coordinator
]()
var
parentCoordinator
:
Coordinator
?
init
(
navigationController
:
UINavigationController
,
settingsRow
:
SettingsRow
)
{
self
.
settingsRow
=
settingsRow
self
.
navigationController
=
navigationController
}
func
start
()
{
DispatchQueue
.
main
.
async
{
let
viewController
=
SettingsDetailsViewController
(
coordinator
:
self
,
settingsRow
:
self
.
settingsRow
)
self
.
navigationController
.
pushViewController
(
viewController
,
animated
:
true
)
}
}
func
viewControllerDidEnd
(
controller
:
UIViewController
)
{
parentCoordinator
?
.
childDidFinish
(
child
:
self
)
}
}
1Weather/Extensions/Dimension+Name.swift
0 → 100644
View file @
b27b7c66
//
// Dimension+Name.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
extension
Dimension
{
private
static
var
fmt
:
MeasurementFormatter
{
let
fmt
=
MeasurementFormatter
()
fmt
.
unitStyle
=
.
long
return
fmt
}
var
name
:
String
{
return
Dimension
.
fmt
.
string
(
from
:
self
)
}
}
1Weather/Extensions/Measurement+String.swift
View file @
b27b7c66
...
@@ -8,33 +8,29 @@
...
@@ -8,33 +8,29 @@
import
Foundation
import
Foundation
extension
Measurement
{
extension
Measurement
{
private
static
var
formatter
:
MeasurementFormatter
{
private
static
func
formatter
(
style
:
Formatter
.
UnitStyle
)
->
MeasurementFormatter
{
let
fmt
=
MeasurementFormatter
()
let
fmt
=
MeasurementFormatter
()
fmt
.
unitStyle
=
.
medium
fmt
.
locale
=
Settings
.
shared
.
locale
fmt
.
numberFormatter
.
maximumFractionDigits
=
0
fmt
.
unitStyle
=
style
return
fmt
}
private
static
var
shortFormatter
:
MeasurementFormatter
{
let
fmt
=
MeasurementFormatter
()
fmt
.
unitStyle
=
.
short
fmt
.
numberFormatter
.
maximumFractionDigits
=
0
fmt
.
numberFormatter
.
maximumFractionDigits
=
0
return
fmt
return
fmt
}
}
var
string
:
String
{
var
string
:
String
{
return
Measurement
.
formatter
.
string
(
from
:
self
)
return
Measurement
.
formatter
(
style
:
.
medium
)
.
string
(
from
:
self
)
}
}
var
shortString
:
String
{
var
shortString
:
String
{
return
Measurement
.
shortFormatter
.
string
(
from
:
self
)
return
Measurement
.
formatter
(
style
:
.
short
)
.
string
(
from
:
self
)
}
var
longString
:
String
{
return
Measurement
.
formatter
(
style
:
.
long
)
.
string
(
from
:
self
)
}
}
}
}
extension
Temperature
{
extension
Temperature
{
var
localeValue
:
Double
{
var
localizedValue
:
Double
{
#warning("Hardcoded value!")
return
self
.
converted
(
to
:
Settings
.
shared
.
temperatureType
.
unit
)
.
value
.
rounded
(
.
down
)
// TODO: replace .fahrenheit with a value from Settings.
return
self
.
converted
(
to
:
.
fahrenheit
)
.
value
.
rounded
(
.
down
)
}
}
}
}
1Weather/Extensions/UIView+InterfaceStyle.swift
View file @
b27b7c66
...
@@ -14,11 +14,18 @@ public enum AppInterfaceStyle {
...
@@ -14,11 +14,18 @@ public enum AppInterfaceStyle {
extension
UIView
{
extension
UIView
{
var
interfaceStyle
:
AppInterfaceStyle
{
var
interfaceStyle
:
AppInterfaceStyle
{
if
#available(iOS 12.0, *)
{
switch
Settings
.
shared
.
appTheme
{
return
traitCollection
.
userInterfaceStyle
==
.
light
?
.
light
:
.
dark
case
.
light
:
}
else
{
return
.
light
return
.
light
case
.
dark
:
return
.
dark
case
.
system
:
if
#available(iOS 12.0, *)
{
return
traitCollection
.
userInterfaceStyle
==
.
light
?
.
light
:
.
dark
}
else
{
return
.
light
}
}
}
}
}
}
}
1Weather/Model/HelperTypes.swift
View file @
b27b7c66
...
@@ -50,12 +50,12 @@ public enum WeatherType: String, CaseIterable {
...
@@ -50,12 +50,12 @@ public enum WeatherType: String, CaseIterable {
}
}
}
}
public
enum
TemperatureType
:
String
{
public
enum
TemperatureType
:
String
,
CaseIterable
{
case
kelvin
=
"temp.kelvin"
case
kelvin
=
"temp.kelvin"
case
celsius
=
"temp.celsius"
case
celsius
=
"temp.celsius"
case
fahrenheit
=
"temp.fahrenheit"
case
fahrenheit
=
"temp.fahrenheit"
var
unit
Temperature
:
UnitTemperature
{
var
unit
:
UnitTemperature
{
switch
self
{
switch
self
{
case
.
kelvin
:
case
.
kelvin
:
return
.
kelvin
return
.
kelvin
...
@@ -67,13 +67,13 @@ public enum TemperatureType:String {
...
@@ -67,13 +67,13 @@ public enum TemperatureType:String {
}
}
}
}
public
enum
WindSpeedType
:
String
{
public
enum
WindSpeedType
:
String
,
CaseIterable
{
case
metersPerSecond
=
"windSpeed.mps"
case
metersPerSecond
=
"windSpeed.mps"
case
kilometersPerHour
=
"windSpeed.kph"
case
kilometersPerHour
=
"windSpeed.kph"
case
milesPerHour
=
"windSpeed.mph"
case
milesPerHour
=
"windSpeed.mph"
case
knots
=
"windSpeed.knots"
case
knots
=
"windSpeed.knots"
var
unit
Speed
:
UnitSpeed
{
var
unit
:
UnitSpeed
{
switch
self
{
switch
self
{
case
.
metersPerSecond
:
case
.
metersPerSecond
:
return
.
metersPerSecond
return
.
metersPerSecond
...
@@ -87,14 +87,14 @@ public enum WindSpeedType:String {
...
@@ -87,14 +87,14 @@ public enum WindSpeedType:String {
}
}
}
}
public
enum
PressureType
:
String
{
public
enum
PressureType
:
String
,
CaseIterable
{
case
inchesOfMercury
=
"pressure.inch"
case
inchesOfMercury
=
"pressure.inch"
case
millibars
=
"pressure.mb"
case
millibars
=
"pressure.mb"
case
millimetersOfMercury
=
"pressure.mm"
case
millimetersOfMercury
=
"pressure.mm"
case
atmosphere
=
"pressure.atm"
case
atmosphere
=
"pressure.atm"
case
kilopascals
=
"pressure.kpa"
case
kilopascals
=
"pressure.kpa"
var
unit
Pressure
:
UnitPressure
{
var
unit
:
UnitPressure
{
switch
self
{
switch
self
{
case
.
inchesOfMercury
:
case
.
inchesOfMercury
:
return
.
inchesOfMercury
return
.
inchesOfMercury
...
@@ -110,11 +110,11 @@ public enum PressureType:String {
...
@@ -110,11 +110,11 @@ public enum PressureType:String {
}
}
}
}
public
enum
DistanceType
:
String
{
public
enum
DistanceType
:
String
,
CaseIterable
{
case
miles
=
"distance.mi"
case
miles
=
"distance.mi"
case
kilometers
=
"distance.km"
case
kilometers
=
"distance.km"
var
unit
Pressure
:
UnitLength
{
var
unit
:
UnitLength
{
switch
self
{
switch
self
{
case
.
miles
:
case
.
miles
:
return
.
miles
return
.
miles
...
...
1Weather/Model/Settings.swift
View file @
b27b7c66
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
//
//
import
UIKit
import
UIKit
import
Localize_Swift
@propertyWrapper
@propertyWrapper
struct
UserDefaultsValue
<
T
>
{
struct
UserDefaultsValue
<
T
>
{
...
@@ -50,4 +51,8 @@ class Settings {
...
@@ -50,4 +51,8 @@ class Settings {
@UserDefaultsValue(key: "distance_type")
@UserDefaultsValue(key: "distance_type")
var
distanceType
=
DistanceType
.
miles
var
distanceType
=
DistanceType
.
miles
var
locale
:
Locale
{
return
Locale
(
identifier
:
Localize
.
currentLanguage
())
}
}
}
1Weather/Resources/Assets.xcassets/checkmark.imageset/Contents.json
0 → 100644
View file @
b27b7c66
{
"images"
:
[
{
"filename"
:
"checkmark.pdf"
,
"idiom"
:
"universal"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
},
"properties"
:
{
"preserves-vector-representation"
:
true
,
"template-rendering-intent"
:
"template"
}
}
1Weather/Resources/Assets.xcassets/checkmark.imageset/checkmark.pdf
0 → 100644
View file @
b27b7c66
File added
1Weather/Resources/Assets.xcassets/checkmark_selected.imageset/Contents.json
0 → 100644
View file @
b27b7c66
{
"images"
:
[
{
"filename"
:
"checkmark_selected.pdf"
,
"idiom"
:
"universal"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
},
"properties"
:
{
"preserves-vector-representation"
:
true
}
}
1Weather/Resources/Assets.xcassets/checkmark_selected.imageset/checkmark_selected.pdf
0 → 100644
View file @
b27b7c66
File added
1Weather/Resources/Assets.xcassets/checkmark_unselected.imageset/Contents.json
0 → 100644
View file @
b27b7c66
{
"images"
:
[
{
"filename"
:
"checkmark_unselected.pdf"
,
"idiom"
:
"universal"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
},
"properties"
:
{
"preserves-vector-representation"
:
true
}
}
1Weather/Resources/Assets.xcassets/checkmark_unselected.imageset/checkmark_unselected.pdf
0 → 100644
View file @
b27b7c66
File added
1Weather/Resources/en.lproj/Localizable.strings
View file @
b27b7c66
...
@@ -113,7 +113,11 @@
...
@@ -113,7 +113,11 @@
"settings.theme.light" = "Light";
"settings.theme.light" = "Light";
"settings.theme.dark" = "Dark";
"settings.theme.dark" = "Dark";
"settings.theme" = "Theme";
"settings.theme" = "Theme";
"settings.units" = "Units";
"settings.unit.temp" = "Temperature";
"settings.unit.temp" = "Temperature";
"settings.unit.wind" = "Wind";
"settings.unit.wind" = "Wind";
"settings.unit.pressure" = "Pressure";
"settings.unit.pressure" = "Pressure";
"settings.unit.distance" = "Distance";
"settings.unit.distance" = "Distance";
"settings.language" = "Language";
"settings.manageNotifications" = "Manage Notifications";
"settings.locationAccess" = "Locations Access";
1Weather/UI/Helpers/ForecastTimePeriod/ForecastTimePeriodView.swift
View file @
b27b7c66
...
@@ -163,9 +163,9 @@ class ForecastTimePeriodView: UIView {
...
@@ -163,9 +163,9 @@ class ForecastTimePeriodView: UIView {
private
func
updateDailyGraphPoints
()
{
private
func
updateDailyGraphPoints
()
{
let
daysCount
=
daily
.
count
let
daysCount
=
daily
.
count
let
maxTemps
=
(
daily
.
map
{
CGFloat
(
$0
.
maxTemp
?
.
local
e
Value
??
0
)
})
let
maxTemps
=
(
daily
.
map
{
CGFloat
(
$0
.
maxTemp
?
.
local
ized
Value
??
0
)
})
let
topMaxTemp
=
maxTemps
.
max
()
??
0
let
topMaxTemp
=
maxTemps
.
max
()
??
0
let
minTemps
=
(
daily
.
map
{
CGFloat
(
$0
.
minTemp
?
.
local
e
Value
??
0
)
})
let
minTemps
=
(
daily
.
map
{
CGFloat
(
$0
.
minTemp
?
.
local
ized
Value
??
0
)
})
let
topMinTemp
=
minTemps
.
max
()
??
0
let
topMinTemp
=
minTemps
.
max
()
??
0
var
maxPoints
=
[
CGPoint
]()
var
maxPoints
=
[
CGPoint
]()
...
@@ -201,7 +201,7 @@ class ForecastTimePeriodView: UIView {
...
@@ -201,7 +201,7 @@ class ForecastTimePeriodView: UIView {
private
func
updateHourlyGraphPoints
()
{
private
func
updateHourlyGraphPoints
()
{
let
hoursCount
=
hourly
.
count
let
hoursCount
=
hourly
.
count
let
temps
=
(
hourly
.
map
{
CGFloat
(
$0
.
temp
?
.
local
e
Value
??
0
)
})
let
temps
=
(
hourly
.
map
{
CGFloat
(
$0
.
temp
?
.
local
ized
Value
??
0
)
})
let
maxTemp
=
temps
.
max
()
??
0
let
maxTemp
=
temps
.
max
()
??
0
var
points
=
[
CGPoint
]()
var
points
=
[
CGPoint
]()
...
...
1Weather/UI/View controllers/Settings/Cells/SettingsCellFactory.swift
View file @
b27b7c66
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
//
//
import
UIKit
import
UIKit
import
Localize_Swift
public
enum
SettingsRow
{
public
enum
SettingsRow
{
case
theme
case
theme
...
@@ -13,6 +14,9 @@ public enum SettingsRow {
...
@@ -13,6 +14,9 @@ public enum SettingsRow {
case
wind
case
wind
case
pressure
case
pressure
case
distance
case
distance
case
language
case
manageNotifications
case
locationAccess
var
roundedCorners
:
CACornerMask
{
var
roundedCorners
:
CACornerMask
{
switch
self
{
switch
self
{
...
@@ -22,6 +26,12 @@ public enum SettingsRow {
...
@@ -22,6 +26,12 @@ public enum SettingsRow {
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
case
.
distance
:
case
.
distance
:
return
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
return
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
case
.
language
:
return
[
.
layerMinXMinYCorner
,
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
,
.
layerMaxXMinYCorner
]
case
.
manageNotifications
:
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
case
.
locationAccess
:
return
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
default
:
default
:
return
[]
return
[]
}
}
...
@@ -30,7 +40,7 @@ public enum SettingsRow {
...
@@ -30,7 +40,7 @@ public enum SettingsRow {
var
localizedName
:
String
{
var
localizedName
:
String
{
switch
self
{
switch
self
{
case
.
theme
:
case
.
theme
:
return
"
settings.theme"
.
localized
()
return
"
"
case
.
temperature
:
case
.
temperature
:
return
"settings.unit.temp"
.
localized
()
return
"settings.unit.temp"
.
localized
()
case
.
wind
:
case
.
wind
:
...
@@ -39,6 +49,12 @@ public enum SettingsRow {
...
@@ -39,6 +49,12 @@ public enum SettingsRow {
return
"settings.unit.pressure"
.
localized
()
return
"settings.unit.pressure"
.
localized
()
case
.
distance
:
case
.
distance
:
return
"settings.unit.distance"
.
localized
()
return
"settings.unit.distance"
.
localized
()
case
.
language
:
return
"settings.language"
.
localized
()
case
.
manageNotifications
:
return
"settings.manageNotifications"
.
localized
()
case
.
locationAccess
:
return
"settings.locationAccess"
.
localized
()
}
}
}
}
}
}
...
@@ -48,6 +64,17 @@ public enum SettingsSection {
...
@@ -48,6 +64,17 @@ public enum SettingsSection {
case
units
case
units
case
language
case
language
case
other
case
other
var
localized
:
String
{
switch
self
{
case
.
theme
:
return
"settings.theme"
.
localized
()
case
.
units
:
return
"settings.units"
.
localized
()
default
:
return
""
}
}
}
}
private
struct
SettingsDataSource
{
private
struct
SettingsDataSource
{
...
@@ -59,7 +86,9 @@ class SettingsCellFactory: CellFactoryProtocol {
...
@@ -59,7 +86,9 @@ class SettingsCellFactory: CellFactoryProtocol {
//Private
//Private
private
let
viewModel
:
SettingsViewModel
private
let
viewModel
:
SettingsViewModel
private
let
sections
:[
SettingsDataSource
]
=
[
SettingsDataSource
(
section
:
.
theme
,
rows
:
[
.
theme
]),
private
let
sections
:[
SettingsDataSource
]
=
[
SettingsDataSource
(
section
:
.
theme
,
rows
:
[
.
theme
]),
SettingsDataSource
(
section
:
.
units
,
rows
:
[
.
temperature
,
.
wind
,
.
pressure
,
.
distance
])]
SettingsDataSource
(
section
:
.
units
,
rows
:
[
.
temperature
,
.
wind
,
.
pressure
,
.
distance
]),
SettingsDataSource
(
section
:
.
language
,
rows
:
[
.
language
]),
SettingsDataSource
(
section
:
.
other
,
rows
:
[
.
manageNotifications
,
.
locationAccess
])]
//Public
//Public
init
(
viewModel
:
SettingsViewModel
)
{
init
(
viewModel
:
SettingsViewModel
)
{
...
@@ -80,14 +109,57 @@ class SettingsCellFactory: CellFactoryProtocol {
...
@@ -80,14 +109,57 @@ class SettingsCellFactory: CellFactoryProtocol {
}
}
public
func
cellFromTableView
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
public
func
cellFromTableView
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
let
type
=
sections
[
indexPath
.
section
]
.
rows
[
indexPath
.
row
]
let
sectionType
=
sections
[
indexPath
.
section
]
.
section
switch
t
ype
{
switch
sectionT
ype
{
case
.
theme
:
case
.
theme
:
return
self
.
dequeueReusableCell
(
type
:
SettingsThemeCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
let
cell
=
self
.
dequeueReusableCell
(
type
:
SettingsThemeCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
default
:
cell
.
configure
(
settings
:
viewModel
.
settings
)
let
cell
=
self
.
dequeueReusableCell
(
type
:
SettingsCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
return
cell
cell
.
configure
(
settingsName
:
type
.
localizedName
,
selectedValue
:
"Some"
,
roundCorners
:
type
.
roundedCorners
)
case
.
units
:
let
rowType
=
sections
[
indexPath
.
section
]
.
rows
[
indexPath
.
row
]
let
cell
=
dequeueReusableCell
(
type
:
SettingsCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
var
name
=
""
var
symbol
=
""
switch
rowType
{
case
.
temperature
:
name
=
viewModel
.
settings
.
temperatureType
.
unit
.
name
symbol
=
viewModel
.
settings
.
temperatureType
.
unit
.
symbol
case
.
wind
:
name
=
viewModel
.
settings
.
windSpeedType
.
unit
.
name
symbol
=
viewModel
.
settings
.
windSpeedType
.
unit
.
symbol
case
.
pressure
:
name
=
viewModel
.
settings
.
pressureType
.
unit
.
name
symbol
=
viewModel
.
settings
.
pressureType
.
unit
.
symbol
case
.
distance
:
name
=
viewModel
.
settings
.
distanceType
.
unit
.
name
symbol
=
viewModel
.
settings
.
distanceType
.
unit
.
symbol
default
:
break
}
cell
.
configure
(
settingsName
:
rowType
.
localizedName
,
selectedValue
:
"
\(
name
)
(
\(
symbol
)
)"
,
roundCorners
:
rowType
.
roundedCorners
)
return
cell
case
.
language
:
let
cell
=
dequeueReusableCell
(
type
:
SettingsCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
configure
(
settingsName
:
SettingsRow
.
language
.
localizedName
,
selectedValue
:
Localize
.
displayNameForLanguage
(
Localize
.
currentLanguage
()),
roundCorners
:
SettingsRow
.
language
.
roundedCorners
)
return
cell
case
.
other
:
let
rowType
=
sections
[
indexPath
.
section
]
.
rows
[
indexPath
.
row
]
let
cell
=
dequeueReusableCell
(
type
:
SettingsCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
switch
rowType
{
case
.
manageNotifications
:
cell
.
configure
(
settingsName
:
rowType
.
localizedName
,
selectedValue
:
""
,
roundCorners
:
rowType
.
roundedCorners
)
case
.
locationAccess
:
cell
.
configure
(
settingsName
:
rowType
.
localizedName
,
selectedValue
:
"--"
,
roundCorners
:
rowType
.
roundedCorners
)
default
:
break
}
return
cell
return
cell
}
}
}
}
...
@@ -95,4 +167,8 @@ class SettingsCellFactory: CellFactoryProtocol {
...
@@ -95,4 +167,8 @@ class SettingsCellFactory: CellFactoryProtocol {
public
func
sectionTypeAt
(
indexPath
:
IndexPath
)
->
SettingsSection
{
public
func
sectionTypeAt
(
indexPath
:
IndexPath
)
->
SettingsSection
{
return
sections
[
indexPath
.
section
]
.
section
return
sections
[
indexPath
.
section
]
.
section
}
}
public
func
rowTypeAt
(
indexPath
:
IndexPath
)
->
SettingsRow
{
return
sections
[
indexPath
.
section
]
.
rows
[
indexPath
.
row
]
}
}
}
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCell.swift
0 → 100644
View file @
b27b7c66
//
// SettingsDetailsCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
class
SettingsDetailsCell
:
UITableViewCell
{
//Private
private
let
container
=
UIView
()
private
let
label
=
UILabel
()
private
let
checkmarkImageView
=
UIImageView
()
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
prepareCell
()
prepareContainer
()
prepareLabel
()
prepareCheckmark
()
updateUI
()
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
override
func
traitCollectionDidChange
(
_
previousTraitCollection
:
UITraitCollection
?)
{
super
.
traitCollectionDidChange
(
previousTraitCollection
)
updateUI
()
}
func
configure
(
item
:
String
,
isSelected
:
Bool
,
roundedConrers
:
CACornerMask
)
{
if
roundedConrers
.
isEmpty
{
self
.
container
.
layer
.
cornerRadius
=
0
}
else
{
self
.
container
.
layer
.
cornerRadius
=
12
self
.
container
.
layer
.
maskedCorners
=
roundedConrers
}
label
.
text
=
item
checkmarkImageView
.
isHidden
=
!
isSelected
}
private
func
updateUI
()
{
contentView
.
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
container
.
backgroundColor
=
ThemeManager
.
currentTheme
.
containerBackgroundColor
switch
interfaceStyle
{
case
.
light
:
label
.
textColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
checkmarkImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
secondaryTextColor
case
.
dark
:
label
.
textColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
checkmarkImageView
.
tintColor
=
ThemeManager
.
currentTheme
.
primaryTextColor
}
}
}
//MARK:- Prepare
private
extension
SettingsDetailsCell
{
func
prepareCell
()
{
selectionStyle
=
.
none
}
func
prepareContainer
()
{
contentView
.
addSubview
(
container
)
container
.
snp
.
makeConstraints
{
(
make
)
in
make
.
top
.
bottom
.
equalToSuperview
()
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
18
)
}
}
func
prepareLabel
()
{
label
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
16
)
label
.
textAlignment
=
.
left
container
.
addSubview
(
label
)
label
.
snp
.
makeConstraints
{
(
make
)
in
make
.
left
.
equalToSuperview
()
.
inset
(
18
)
make
.
centerY
.
equalToSuperview
()
make
.
top
.
bottom
.
equalToSuperview
()
.
inset
(
18
)
}
}
func
prepareCheckmark
()
{
checkmarkImageView
.
contentMode
=
.
scaleAspectFit
checkmarkImageView
.
image
=
UIImage
(
named
:
"checkmark"
)
container
.
addSubview
(
checkmarkImageView
)
checkmarkImageView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
width
.
height
.
equalTo
(
12
)
make
.
centerY
.
equalToSuperview
()
make
.
right
.
equalToSuperview
()
.
inset
(
30
)
}
}
}
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCellFactory.swift
0 → 100644
View file @
b27b7c66
//
// SettingsDetailsCellFactory.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
class
SettingsDetailsCellFactory
:
CellFactoryProtocol
{
//Private
private
let
viewModel
:
SettingsDetailsViewModel
//Public
public
var
numberOfSections
:
Int
{
return
1
}
init
(
viewModel
:
SettingsDetailsViewModel
)
{
self
.
viewModel
=
viewModel
}
public
func
numberOfRows
(
inSection
section
:
Int
)
->
Int
{
switch
viewModel
.
rowType
{
case
.
temperature
:
return
viewModel
.
temperatures
.
count
case
.
wind
:
return
viewModel
.
winds
.
count
case
.
pressure
:
return
viewModel
.
pressures
.
count
case
.
distance
:
return
viewModel
.
distances
.
count
case
.
language
:
return
viewModel
.
languages
.
count
default
:
return
0
}
}
public
func
registerCells
(
on
tableView
:
UITableView
)
{
self
.
registerCell
(
type
:
SettingsDetailsCell
.
self
,
tableView
:
tableView
)
}
public
func
cellFromTableView
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
let
cell
=
dequeueReusableCell
(
type
:
SettingsDetailsCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
var
mask
:
CACornerMask
=
[]
switch
indexPath
.
row
{
case
0
:
mask
=
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
case
numberOfRows
(
inSection
:
1
)
-
1
:
mask
=
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
default
:
break
}
switch
viewModel
.
rowType
{
case
.
temperature
:
cell
.
configure
(
item
:
viewModel
.
temperatures
[
indexPath
.
row
],
isSelected
:
indexPath
.
row
==
viewModel
.
selectedTemperatureIndex
,
roundedConrers
:
mask
)
case
.
wind
:
cell
.
configure
(
item
:
viewModel
.
winds
[
indexPath
.
row
],
isSelected
:
indexPath
.
row
==
viewModel
.
selectedWindIndex
,
roundedConrers
:
mask
)
case
.
pressure
:
cell
.
configure
(
item
:
viewModel
.
pressures
[
indexPath
.
row
],
isSelected
:
indexPath
.
row
==
viewModel
.
selectedPressureIndex
,
roundedConrers
:
mask
)
case
.
distance
:
cell
.
configure
(
item
:
viewModel
.
distances
[
indexPath
.
row
],
isSelected
:
indexPath
.
row
==
viewModel
.
selectedDistanceIndex
,
roundedConrers
:
mask
)
case
.
language
:
cell
.
configure
(
item
:
viewModel
.
languages
[
indexPath
.
row
],
isSelected
:
indexPath
.
row
==
viewModel
.
selectedLanguageIndex
,
roundedConrers
:
mask
)
default
:
break
}
return
cell
}
}
1Weather/UI/View controllers/Settings/Cells/SettingsThemeCell.swift
View file @
b27b7c66
...
@@ -10,6 +10,8 @@ import UIKit
...
@@ -10,6 +10,8 @@ import UIKit
class
SettingsThemeCell
:
UITableViewCell
{
class
SettingsThemeCell
:
UITableViewCell
{
//Private
//Private
private
let
container
=
UIView
()
private
let
container
=
UIView
()
private
let
checkmarkSelectedImage
=
UIImage
(
named
:
"checkmark_selected"
)
private
let
checkmarkUnselectedImage
=
UIImage
(
named
:
"checkmark_unselected"
)
private
let
lightThemeImageView
=
UIImageView
()
private
let
lightThemeImageView
=
UIImageView
()
private
let
lightThemeLabel
=
UILabel
()
private
let
lightThemeLabel
=
UILabel
()
private
let
lightThemeButton
=
UIButton
()
private
let
lightThemeButton
=
UIButton
()
...
@@ -72,6 +74,9 @@ class SettingsThemeCell: UITableViewCell {
...
@@ -72,6 +74,9 @@ class SettingsThemeCell: UITableViewCell {
//Public
//Public
public
func
configure
(
settings
:
Settings
)
{
public
func
configure
(
settings
:
Settings
)
{
lightThemeButton
.
setImage
(
interfaceStyle
==
.
light
?
checkmarkSelectedImage
:
checkmarkUnselectedImage
,
for
:
.
normal
)
darkThemeButton
.
setImage
(
interfaceStyle
==
.
dark
?
checkmarkSelectedImage
:
checkmarkUnselectedImage
,
for
:
.
normal
)
automaticSwitchButton
.
isOn
=
settings
.
automaticSwitchTheme
}
}
}
}
...
...
1Weather/UI/View controllers/Settings/SettingsDetailsViewController.swift
0 → 100644
View file @
b27b7c66
//
// SettingsDetailsViewController.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
class
SettingsDetailsViewController
:
UIViewController
{
//Private
private
let
viewModel
:
SettingsDetailsViewModel
private
let
coordinator
:
SettingsDetailsCoordinator
private
let
cellFactory
:
SettingsDetailsCellFactory
private
let
tableView
=
UITableView
()
init
(
coordinator
:
SettingsDetailsCoordinator
,
settingsRow
:
SettingsRow
)
{
self
.
coordinator
=
coordinator
self
.
viewModel
=
SettingsDetailsViewModel
(
rowType
:
settingsRow
)
self
.
cellFactory
=
SettingsDetailsCellFactory
(
viewModel
:
self
.
viewModel
)
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
}
required
init
?(
coder
:
NSCoder
)
{
fatalError
(
"init(coder:) has not been implemented"
)
}
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
prepareController
()
prepareTable
()
}
}
//MARK:- Prepare
private
extension
SettingsDetailsViewController
{
func
prepareController
()
{
navigationItem
.
title
=
viewModel
.
rowType
.
localizedName
}
func
prepareTable
()
{
cellFactory
.
registerCells
(
on
:
tableView
)
tableView
.
separatorStyle
=
.
none
tableView
.
dataSource
=
self
tableView
.
delegate
=
self
tableView
.
separatorStyle
=
.
none
tableView
.
tableFooterView
=
UIView
()
tableView
.
rowHeight
=
UITableView
.
automaticDimension
tableView
.
estimatedRowHeight
=
UITableView
.
automaticDimension
view
.
addSubview
(
tableView
)
tableView
.
snp
.
makeConstraints
{
(
make
)
in
make
.
edges
.
equalToSuperview
()
}
}
}
//MARK:- UITableView Data Source
extension
SettingsDetailsViewController
:
UITableViewDataSource
{
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
return
cellFactory
.
numberOfRows
(
inSection
:
section
)
}
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
return
cellFactory
.
cellFromTableView
(
tableView
:
tableView
,
indexPath
:
indexPath
)
}
}
//MARK:- UITableView Delegate
extension
SettingsDetailsViewController
:
UITableViewDelegate
{
}
1Weather/UI/View controllers/Settings/SettingsViewController.swift
View file @
b27b7c66
...
@@ -12,7 +12,7 @@ class SettingsViewController: UIViewController {
...
@@ -12,7 +12,7 @@ class SettingsViewController: UIViewController {
private
let
coordinator
:
SettingsCoordinator
private
let
coordinator
:
SettingsCoordinator
private
let
settingsCellFactory
:
SettingsCellFactory
private
let
settingsCellFactory
:
SettingsCellFactory
private
let
viewModel
:
SettingsViewModel
private
let
viewModel
:
SettingsViewModel
private
let
tableView
=
UITableView
()
private
let
tableView
=
UITableView
(
frame
:
.
zero
,
style
:
.
grouped
)
init
(
coordinator
:
SettingsCoordinator
,
settingsViewModel
:
SettingsViewModel
)
{
init
(
coordinator
:
SettingsCoordinator
,
settingsViewModel
:
SettingsViewModel
)
{
...
@@ -65,7 +65,10 @@ private extension SettingsViewController {
...
@@ -65,7 +65,10 @@ private extension SettingsViewController {
func
prepareTableView
()
{
func
prepareTableView
()
{
settingsCellFactory
.
registerCells
(
on
:
tableView
)
settingsCellFactory
.
registerCells
(
on
:
tableView
)
tableView
.
separatorStyle
=
.
none
tableView
.
separatorStyle
=
.
none
tableView
.
contentInset
=
.
init
(
top
:
0
,
left
:
0
,
bottom
:
24
,
right
:
0
)
tableView
.
contentInsetAdjustmentBehavior
=
.
never
tableView
.
dataSource
=
self
tableView
.
dataSource
=
self
tableView
.
delegate
=
self
tableView
.
separatorStyle
=
.
none
tableView
.
separatorStyle
=
.
none
tableView
.
tableFooterView
=
UIView
()
tableView
.
tableFooterView
=
UIView
()
tableView
.
rowHeight
=
UITableView
.
automaticDimension
tableView
.
rowHeight
=
UITableView
.
automaticDimension
...
@@ -96,24 +99,49 @@ extension SettingsViewController: UITableViewDataSource {
...
@@ -96,24 +99,49 @@ extension SettingsViewController: UITableViewDataSource {
//MARK:- UITableView Delegate
//MARK:- UITableView Delegate
extension
SettingsViewController
:
UITableViewDelegate
{
extension
SettingsViewController
:
UITableViewDelegate
{
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
func
tableView
(
_
tableView
:
UITableView
,
viewForHeaderInSection
section
:
Int
)
->
UIView
?
{
switch
settingsCellFactory
.
sectionTypeAt
(
indexPath
:
[
section
,
0
])
{
let
settingsSection
=
settingsCellFactory
.
sectionTypeAt
(
indexPath
:
[
section
,
0
])
let
view
=
UIView
()
view
.
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
switch
settingsSection
{
case
.
theme
,
.
units
:
case
.
theme
,
.
units
:
let
view
=
UIView
()
let
label
=
UILabel
()
let
label
=
UILabel
()
label
.
text
=
settingsSection
.
localized
view
.
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
label
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
18
)
label
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
18
)
label
.
textColor
=
view
.
interfaceStyle
==
.
light
?
ThemeManager
.
currentTheme
.
secondaryTextColor
:
ThemeManager
.
currentTheme
.
primaryTextColor
view
.
addSubview
(
label
)
view
.
snp
.
makeConstraints
{
(
make
)
in
label
.
snp
.
makeConstraints
{
(
make
)
in
make
.
height
.
equalTo
(
24
)
make
.
left
.
equalToSuperview
()
.
inset
(
24
)
make
.
bottom
.
equalToSuperview
()
.
inset
(
9
)
}
}
return
view
default
:
default
:
return
nil
break
}
}
return
view
}
func
tableView
(
_
tableView
:
UITableView
,
heightForFooterInSection
section
:
Int
)
->
CGFloat
{
return
.
leastNormalMagnitude
}
func
tableView
(
_
tableView
:
UITableView
,
viewForFooterInSection
section
:
Int
)
->
UIView
?
{
return
nil
}
}
func
tableView
(
_
tableView
:
UITableView
,
heightForHeaderInSection
section
:
Int
)
->
CGFloat
{
func
tableView
(
_
tableView
:
UITableView
,
heightForHeaderInSection
section
:
Int
)
->
CGFloat
{
return
UITableView
.
automaticDimension
switch
settingsCellFactory
.
sectionTypeAt
(
indexPath
:
[
section
,
0
])
{
case
.
theme
,
.
units
:
return
57
default
:
return
24
}
}
func
tableView
(
_
tableView
:
UITableView
,
didSelectRowAt
indexPath
:
IndexPath
)
{
coordinator
.
openDetailsViewController
(
rowType
:
settingsCellFactory
.
rowTypeAt
(
indexPath
:
indexPath
))
}
}
}
}
1Weather/ViewModels/SettingsDetailsViewModel.swift
0 → 100644
View file @
b27b7c66
//
// SettingsDetailsViewModel.swift
// 1Weather
//
// Created by Dmitry Stepanets on 27.03.2021.
//
import
UIKit
import
Localize_Swift
class
SettingsDetailsViewModel
:
ViewModelProtocol
{
//Public
let
rowType
:
SettingsRow
weak
var
delegate
:
ViewModelDelegate
?
var
temperatures
:[
String
]
{
return
TemperatureType
.
allCases
.
map
{
$0
.
rawValue
.
localized
()
}
}
var
winds
:[
String
]
{
return
WindSpeedType
.
allCases
.
map
{
$0
.
rawValue
.
localized
()
}
}
var
pressures
:[
String
]
{
return
PressureType
.
allCases
.
map
{
$0
.
rawValue
.
localized
()
}
}
var
distances
:[
String
]
{
return
DistanceType
.
allCases
.
map
{
$0
.
rawValue
.
localized
()
}
}
var
languages
:[
String
]
{
return
Localize
.
availableLanguages
()
}
//Selected
var
selectedTemperatureIndex
:
Int
{
return
TemperatureType
.
allCases
.
firstIndex
{
Settings
.
shared
.
temperatureType
==
$0
}
??
-
1
}
var
selectedWindIndex
:
Int
{
return
WindSpeedType
.
allCases
.
firstIndex
{
Settings
.
shared
.
windSpeedType
==
$0
}
??
-
1
}
var
selectedPressureIndex
:
Int
{
return
PressureType
.
allCases
.
firstIndex
{
Settings
.
shared
.
pressureType
==
$0
}
??
-
1
}
var
selectedDistanceIndex
:
Int
{
return
DistanceType
.
allCases
.
firstIndex
{
Settings
.
shared
.
distanceType
==
$0
}
??
-
1
}
var
selectedLanguageIndex
:
Int
{
return
Localize
.
availableLanguages
()
.
firstIndex
{
$0
==
Localize
.
currentLanguage
()}
??
-
1
}
init
(
rowType
:
SettingsRow
)
{
self
.
rowType
=
rowType
}
}
1Weather/ViewModels/SettingsViewModel.swift
View file @
b27b7c66
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
import
UIKit
import
UIKit
class
SettingsViewModel
:
ViewModelProtocol
{
class
SettingsViewModel
:
ViewModelProtocol
{
let
settings
=
Settings
.
shared
weak
var
delegate
:
ViewModelDelegate
?
}
}
Pods/Pods.xcodeproj/xcuserdata/dstepanets.xcuserdatad/xcschemes/xcschememanagement.plist
View file @
b27b7c66
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
<
k
e
y
>
Cirque.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
k
e
y
>
Cirque.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
int
e
g
e
r
>
4
<
/int
e
g
e
r
>
<
int
e
g
e
r
>
6
<
/int
e
g
e
r
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
k
e
y
>
Localize-Swift.xcscheme
<
/k
e
y
>
<
k
e
y
>
Localize-Swift.xcscheme
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
<
k
e
y
>
Localize-Swift.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
k
e
y
>
Localize-Swift.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
int
e
g
e
r
>
5
<
/int
e
g
e
r
>
<
int
e
g
e
r
>
4
<
/int
e
g
e
r
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
k
e
y
>
Pods-1Weather.xcscheme
<
/k
e
y
>
<
k
e
y
>
Pods-1Weather.xcscheme
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
...
@@ -52,7 +52,7 @@
...
@@ -52,7 +52,7 @@
<
k
e
y
>
XMLCoder.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
k
e
y
>
XMLCoder.xcscheme_
^#
shared
#^
_
<
/k
e
y
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
k
e
y
>
orderHint
<
/k
e
y
>
<
int
e
g
e
r
>
3
<
/int
e
g
e
r
>
<
int
e
g
e
r
>
5
<
/int
e
g
e
r
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
k
e
y
>
SuppressBuildableAutocreation
<
/k
e
y
>
<
k
e
y
>
SuppressBuildableAutocreation
<
/k
e
y
>
...
...
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