Commit d9bea788 by Dmitriy Stepanets

Added menu view controller

parent 1ecdd9d8
...@@ -24,9 +24,18 @@ ...@@ -24,9 +24,18 @@
CD251EDC26036E5400ED7A65 /* DayTimePrecipitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD251EDB26036E5400ED7A65 /* DayTimePrecipitationView.swift */; }; CD251EDC26036E5400ED7A65 /* DayTimePrecipitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD251EDB26036E5400ED7A65 /* DayTimePrecipitationView.swift */; };
CD2B2140260A366B00AB918A /* UIView+InterfaceStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2B213F260A366B00AB918A /* UIView+InterfaceStyle.swift */; }; CD2B2140260A366B00AB918A /* UIView+InterfaceStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2B213F260A366B00AB918A /* UIView+InterfaceStyle.swift */; };
CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */; }; CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */; };
CD32CE04260C742300235081 /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE03260C742300235081 /* MenuViewController.swift */; };
CD32CE08260C743B00235081 /* MenuViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE07260C743B00235081 /* MenuViewModel.swift */; };
CD32CE0B260C744A00235081 /* MenuCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE0A260C744A00235081 /* MenuCoordinator.swift */; };
CD32CE0E260C770E00235081 /* MenuHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE0D260C770E00235081 /* MenuHeaderView.swift */; };
CD32CE12260C77B400235081 /* MenuBuyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE11260C77B400235081 /* MenuBuyButton.swift */; };
CD32CE16260C77C600235081 /* MenuHeaderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD32CE15260C77C600235081 /* MenuHeaderButton.swift */; };
CD35DFCC260341B000F2138F /* Calendar+TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFCB260341B000F2138F /* Calendar+TimeZone.swift */; }; CD35DFCC260341B000F2138F /* Calendar+TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFCB260341B000F2138F /* Calendar+TimeZone.swift */; };
CD35DFD0260344A500F2138F /* ForecastConditionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFCF260344A500F2138F /* ForecastConditionView.swift */; }; CD35DFD0260344A500F2138F /* ForecastConditionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFCF260344A500F2138F /* ForecastConditionView.swift */; };
CD35DFD426034BCD00F2138F /* UIStackView+RemoveAll.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFD326034BCD00F2138F /* UIStackView+RemoveAll.swift */; }; CD35DFD426034BCD00F2138F /* UIStackView+RemoveAll.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD35DFD326034BCD00F2138F /* UIStackView+RemoveAll.swift */; };
CD37D3D6260C93B3002669D6 /* MenuCellFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD37D3D5260C93B3002669D6 /* MenuCellFactory.swift */; };
CD37D3DE260C9E37002669D6 /* MenuCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD37D3DD260C9E37002669D6 /* MenuCell.swift */; };
CD37D3E5260CB05C002669D6 /* MenuFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD37D3E4260CB05C002669D6 /* MenuFooterView.swift */; };
CD39F2EE25DE858D009FE398 /* NotificationName+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2ED25DE858D009FE398 /* NotificationName+Localization.swift */; }; CD39F2EE25DE858D009FE398 /* NotificationName+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2ED25DE858D009FE398 /* NotificationName+Localization.swift */; };
CD39F2F225DE94C4009FE398 /* CitySunCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F125DE94C4009FE398 /* CitySunCell.swift */; }; CD39F2F225DE94C4009FE398 /* CitySunCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F125DE94C4009FE398 /* CitySunCell.swift */; };
CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F425DE9571009FE398 /* ArrowButton.swift */; }; CD39F2F525DE9571009FE398 /* ArrowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD39F2F425DE9571009FE398 /* ArrowButton.swift */; };
...@@ -129,9 +138,18 @@ ...@@ -129,9 +138,18 @@
CD251EDB26036E5400ED7A65 /* DayTimePrecipitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimePrecipitationView.swift; sourceTree = "<group>"; }; CD251EDB26036E5400ED7A65 /* DayTimePrecipitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayTimePrecipitationView.swift; sourceTree = "<group>"; };
CD2B213F260A366B00AB918A /* UIView+InterfaceStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+InterfaceStyle.swift"; sourceTree = "<group>"; }; CD2B213F260A366B00AB918A /* UIView+InterfaceStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+InterfaceStyle.swift"; sourceTree = "<group>"; };
CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDescriptionView.swift; sourceTree = "<group>"; }; CD32CDFE260B2E5400235081 /* ForecastDescriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastDescriptionView.swift; sourceTree = "<group>"; };
CD32CE03260C742300235081 /* MenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
CD32CE07260C743B00235081 /* MenuViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewModel.swift; sourceTree = "<group>"; };
CD32CE0A260C744A00235081 /* MenuCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCoordinator.swift; sourceTree = "<group>"; };
CD32CE0D260C770E00235081 /* MenuHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuHeaderView.swift; sourceTree = "<group>"; };
CD32CE11260C77B400235081 /* MenuBuyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBuyButton.swift; sourceTree = "<group>"; };
CD32CE15260C77C600235081 /* MenuHeaderButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuHeaderButton.swift; sourceTree = "<group>"; };
CD35DFCB260341B000F2138F /* Calendar+TimeZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Calendar+TimeZone.swift"; sourceTree = "<group>"; }; CD35DFCB260341B000F2138F /* Calendar+TimeZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Calendar+TimeZone.swift"; sourceTree = "<group>"; };
CD35DFCF260344A500F2138F /* ForecastConditionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastConditionView.swift; sourceTree = "<group>"; }; CD35DFCF260344A500F2138F /* ForecastConditionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastConditionView.swift; sourceTree = "<group>"; };
CD35DFD326034BCD00F2138F /* UIStackView+RemoveAll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+RemoveAll.swift"; sourceTree = "<group>"; }; CD35DFD326034BCD00F2138F /* UIStackView+RemoveAll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+RemoveAll.swift"; sourceTree = "<group>"; };
CD37D3D5260C93B3002669D6 /* MenuCellFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCellFactory.swift; sourceTree = "<group>"; };
CD37D3DD260C9E37002669D6 /* MenuCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCell.swift; sourceTree = "<group>"; };
CD37D3E4260CB05C002669D6 /* MenuFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFooterView.swift; sourceTree = "<group>"; };
CD39F2ED25DE858D009FE398 /* NotificationName+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationName+Localization.swift"; sourceTree = "<group>"; }; CD39F2ED25DE858D009FE398 /* NotificationName+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationName+Localization.swift"; sourceTree = "<group>"; };
CD39F2F125DE94C4009FE398 /* CitySunCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CitySunCell.swift; sourceTree = "<group>"; }; CD39F2F125DE94C4009FE398 /* CitySunCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CitySunCell.swift; sourceTree = "<group>"; };
CD39F2F425DE9571009FE398 /* ArrowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowButton.swift; sourceTree = "<group>"; }; CD39F2F425DE9571009FE398 /* ArrowButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowButton.swift; sourceTree = "<group>"; };
...@@ -329,6 +347,7 @@ ...@@ -329,6 +347,7 @@
CD17C5FA25D15B6B00EE884E /* AppCoordinator.swift */, CD17C5FA25D15B6B00EE884E /* AppCoordinator.swift */,
CD17C5FE25D15B7C00EE884E /* TodayCoordinator.swift */, CD17C5FE25D15B7C00EE884E /* TodayCoordinator.swift */,
CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */, CDE18DCC25D1666700C80ED9 /* ForecastCoordinator.swift */,
CD32CE0A260C744A00235081 /* MenuCoordinator.swift */,
); );
path = Coordinators; path = Coordinators;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -342,6 +361,27 @@ ...@@ -342,6 +361,27 @@
path = ForecastPrecipitationCell; path = ForecastPrecipitationCell;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CD32CE02260C740600235081 /* Menu */ = {
isa = PBXGroup;
children = (
CD32CE10260C779400235081 /* Header */,
CD37D3D4260C92DD002669D6 /* Cells */,
CD37D3E3260CB049002669D6 /* Footer */,
CD32CE03260C742300235081 /* MenuViewController.swift */,
);
path = Menu;
sourceTree = "<group>";
};
CD32CE10260C779400235081 /* Header */ = {
isa = PBXGroup;
children = (
CD32CE0D260C770E00235081 /* MenuHeaderView.swift */,
CD32CE11260C77B400235081 /* MenuBuyButton.swift */,
CD32CE15260C77C600235081 /* MenuHeaderButton.swift */,
);
path = Header;
sourceTree = "<group>";
};
CD35DFCE2603448300F2138F /* ForecastInfoCell */ = { CD35DFCE2603448300F2138F /* ForecastInfoCell */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -351,12 +391,30 @@ ...@@ -351,12 +391,30 @@
path = ForecastInfoCell; path = ForecastInfoCell;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
CD37D3D4260C92DD002669D6 /* Cells */ = {
isa = PBXGroup;
children = (
CD37D3D5260C93B3002669D6 /* MenuCellFactory.swift */,
CD37D3DD260C9E37002669D6 /* MenuCell.swift */,
);
path = Cells;
sourceTree = "<group>";
};
CD37D3E3260CB049002669D6 /* Footer */ = {
isa = PBXGroup;
children = (
CD37D3E4260CB05C002669D6 /* MenuFooterView.swift */,
);
path = Footer;
sourceTree = "<group>";
};
CD647D0025ED07AF0034578B /* ViewModels */ = { CD647D0025ED07AF0034578B /* ViewModels */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD647D0125ED07D60034578B /* TodayViewModel.swift */, CD647D0125ED07D60034578B /* TodayViewModel.swift */,
CD8E041125F8F775001785B6 /* ForecastViewModel.swift */, CD8E041125F8F775001785B6 /* ForecastViewModel.swift */,
CD647D0525ED08050034578B /* ViewModelProtocol.swift */, CD647D0525ED08050034578B /* ViewModelProtocol.swift */,
CD32CE07260C743B00235081 /* MenuViewModel.swift */,
); );
path = ViewModels; path = ViewModels;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -366,6 +424,7 @@ ...@@ -366,6 +424,7 @@
children = ( children = (
CD17C5F425D15B3400EE884E /* Today */, CD17C5F425D15B3400EE884E /* Today */,
CDE18DCF25D166DD00C80ED9 /* Forecast */, CDE18DCF25D166DD00C80ED9 /* Forecast */,
CD32CE02260C740600235081 /* Menu */,
CD82300925D6B2AF00A05501 /* AppTabBarController.swift */, CD82300925D6B2AF00A05501 /* AppTabBarController.swift */,
); );
path = "View controllers"; path = "View controllers";
...@@ -732,6 +791,7 @@ ...@@ -732,6 +791,7 @@
CD35DFD0260344A500F2138F /* ForecastConditionView.swift in Sources */, CD35DFD0260344A500F2138F /* ForecastConditionView.swift in Sources */,
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 */,
CEAFF09225DFC71D00DF4EBF /* HelperTypes.swift in Sources */, CEAFF09225DFC71D00DF4EBF /* HelperTypes.swift in Sources */,
CDE2BF222609D4250085C930 /* ForecastWindSpeedCell.swift in Sources */, CDE2BF222609D4250085C930 /* ForecastWindSpeedCell.swift in Sources */,
CDA5543025EFA13F00A2E08C /* Measurement+String.swift in Sources */, CDA5543025EFA13F00A2E08C /* Measurement+String.swift in Sources */,
...@@ -746,6 +806,7 @@ ...@@ -746,6 +806,7 @@
CDC6124F25E7964700188DA7 /* CityDayTimesCell.swift in Sources */, CDC6124F25E7964700188DA7 /* CityDayTimesCell.swift in Sources */,
CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */, CD593BC226088A5900C93428 /* TimePeriodOffsetHolder.swift in Sources */,
CD17C5FB25D15B6B00EE884E /* AppCoordinator.swift in Sources */, CD17C5FB25D15B6B00EE884E /* AppCoordinator.swift in Sources */,
CD32CE0E260C770E00235081 /* MenuHeaderView.swift in Sources */,
CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */, CD15DB3D25DA6C5100024727 /* ForecastTimePeriodControl.swift in Sources */,
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */, CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */,
CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */, CDD0F1EE25725BCF00CF5017 /* ThemeManager.swift in Sources */,
...@@ -759,6 +820,7 @@ ...@@ -759,6 +820,7 @@
CEAFF08F25DFC6ED00DF4EBF /* HourlyWeather.swift in Sources */, CEAFF08F25DFC6ED00DF4EBF /* HourlyWeather.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 */,
CDE18DD825D16CB200C80ED9 /* NavigationCityButton.swift in Sources */, CDE18DD825D16CB200C80ED9 /* NavigationCityButton.swift in Sources */,
CD593BDC2608CDF100C93428 /* Date+Now.swift in Sources */, CD593BDC2608CDF100C93428 /* Date+Now.swift in Sources */,
CD17C60225D15C8500EE884E /* CoordinatorProtocol.swift in Sources */, CD17C60225D15C8500EE884E /* CoordinatorProtocol.swift in Sources */,
...@@ -780,6 +842,7 @@ ...@@ -780,6 +842,7 @@
CD8E041625F8F91B001785B6 /* ForecastCellFactory.swift in Sources */, CD8E041625F8F91B001785B6 /* ForecastCellFactory.swift in Sources */,
CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */, CDC6125325E79C8F00188DA7 /* DayTimeView.swift in Sources */,
CD251EDC26036E5400ED7A65 /* DayTimePrecipitationView.swift in Sources */, CD251EDC26036E5400ED7A65 /* DayTimePrecipitationView.swift in Sources */,
CD32CE04260C742300235081 /* MenuViewController.swift in Sources */,
CD86246925E672A20097F3FB /* PrecipButton.swift in Sources */, CD86246925E672A20097F3FB /* PrecipButton.swift in Sources */,
CD3F6E6C25FA5A90002DB99B /* PeriodButtonProtocol.swift in Sources */, CD3F6E6C25FA5A90002DB99B /* PeriodButtonProtocol.swift in Sources */,
CEDE4E8225EEFD56007457E9 /* WdtWeatherCode.swift in Sources */, CEDE4E8225EEFD56007457E9 /* WdtWeatherCode.swift in Sources */,
...@@ -787,6 +850,7 @@ ...@@ -787,6 +850,7 @@
CE9D181625ECB8370028D9D7 /* MulticastDelegate.swift in Sources */, CE9D181625ECB8370028D9D7 /* MulticastDelegate.swift in Sources */,
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */, CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */,
CDC6126225E8DAB800188DA7 /* CityMoonCell.swift in Sources */, CDC6126225E8DAB800188DA7 /* CityMoonCell.swift in Sources */,
CD37D3D6260C93B3002669D6 /* MenuCellFactory.swift in Sources */,
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */, CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */, CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
CD35DFCC260341B000F2138F /* Calendar+TimeZone.swift in Sources */, CD35DFCC260341B000F2138F /* Calendar+TimeZone.swift in Sources */,
...@@ -798,9 +862,12 @@ ...@@ -798,9 +862,12 @@
CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */, CEC5276025E92DDA00DA58A5 /* WdtHourlySummary.swift in Sources */,
CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */, CDE18DCA25D165F100C80ED9 /* UITabBarController+Append.swift in Sources */,
CDE2BF252609D9140085C930 /* ForecastWindButton.swift in Sources */, CDE2BF252609D9140085C930 /* ForecastWindButton.swift in Sources */,
CD32CE16260C77C600235081 /* MenuHeaderButton.swift in Sources */,
CD251ED82603633800ED7A65 /* ForecastPrecipitationCell.swift in Sources */, CD251ED82603633800ED7A65 /* ForecastPrecipitationCell.swift in Sources */,
CD86246125E662BC0097F3FB /* SunUvLineView.swift in Sources */, CD86246125E662BC0097F3FB /* SunUvLineView.swift in Sources */,
CD32CE0B260C744A00235081 /* MenuCoordinator.swift in Sources */,
CEC526FA25E7959A00DA58A5 /* WeatherSource.swift in Sources */, CEC526FA25E7959A00DA58A5 /* WeatherSource.swift in Sources */,
CD37D3DE260C9E37002669D6 /* MenuCell.swift in Sources */,
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */, CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */,
CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */, CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */,
CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */, CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */,
...@@ -818,6 +885,7 @@ ...@@ -818,6 +885,7 @@
CDA5542D25EF7C9700A2E08C /* ReusableCellProtocol.swift in Sources */, CDA5542D25EF7C9700A2E08C /* ReusableCellProtocol.swift in Sources */,
CD647D0625ED08050034578B /* ViewModelProtocol.swift in Sources */, CD647D0625ED08050034578B /* ViewModelProtocol.swift in Sources */,
CD8E041225F8F775001785B6 /* ForecastViewModel.swift in Sources */, CD8E041225F8F775001785B6 /* ForecastViewModel.swift in Sources */,
CD32CE12260C77B400235081 /* MenuBuyButton.swift in Sources */,
CD86246C25E6826A0097F3FB /* InnerShadowLayer.swift in Sources */, CD86246C25E6826A0097F3FB /* InnerShadowLayer.swift in Sources */,
CEAFF0A325E0FF0800DF4EBF /* LocationManager.swift in Sources */, CEAFF0A325E0FF0800DF4EBF /* LocationManager.swift in Sources */,
CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */, CEAD00A12577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift in Sources */,
......
...@@ -33,7 +33,7 @@ class AppCoordinator: Coordinator { ...@@ -33,7 +33,7 @@ class AppCoordinator: Coordinator {
radarCoordinator.start() radarCoordinator.start()
childCoordinators.append(radarCoordinator) childCoordinators.append(radarCoordinator)
let menuCoordinator = ForecastCoordinator(tabBarController: tabBarController) let menuCoordinator = MenuCoordinator(tabBarController: tabBarController)
menuCoordinator.start() menuCoordinator.start()
childCoordinators.append(menuCoordinator) childCoordinators.append(menuCoordinator)
......
//
// MenuCoordinator.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuCoordinator: Coordinator {
//Private
private let menuViewModel = MenuViewModel()
private let navigationController = UINavigationController(nibName: nil, bundle: nil)
private var tabBarController:UITabBarController?
//Public
var childCoordinators = [Coordinator]()
var parentCoordinator: Coordinator?
init(tabBarController:UITabBarController) {
self.tabBarController = tabBarController
}
func start() {
let menuViewController = MenuViewController(menuViewModel: menuViewModel)
navigationController.viewControllers = [menuViewController]
tabBarController?.add(viewController: navigationController)
}
}
...@@ -36,4 +36,32 @@ extension UITableView { ...@@ -36,4 +36,32 @@ extension UITableView {
headerView.removeConstraints(temporaryWidthConstraints) headerView.removeConstraints(temporaryWidthConstraints)
headerView.translatesAutoresizingMaskIntoConstraints = true headerView.translatesAutoresizingMaskIntoConstraints = true
} }
func layoutTableFooterView() {
guard let footerView = self.tableFooterView else { return }
footerView.translatesAutoresizingMaskIntoConstraints = false
let footerWidth = footerView.bounds.size.width;
let temporaryWidthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "[footerView(width)]",
options: NSLayoutConstraint.FormatOptions(rawValue: UInt(0)),
metrics: ["width": footerWidth],
views: ["footerView": footerView])
footerView.addConstraints(temporaryWidthConstraints)
footerView.setNeedsLayout()
footerView.layoutIfNeeded()
let footerSize = footerView.systemLayoutSizeFitting(UITableView.layoutFittingCompressedSize)
let height = footerSize.height
var frame = footerView.frame
frame.size.height = height
footerView.frame = frame
self.tableFooterView = footerView
footerView.removeConstraints(temporaryWidthConstraints)
footerView.translatesAutoresizingMaskIntoConstraints = true
}
} }
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "menu_about.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_ad.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_faq.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_help.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_privacyPolicy.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_radar.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "menu_rateUs.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "menu_settings.pdf",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "menu_settings_light.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
{
"images" : [
{
"filename" : "menu_tv.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "premium.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
{
"images" : [
{
"filename" : "version_icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "version_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "version_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -88,3 +88,17 @@ ...@@ -88,3 +88,17 @@
"tabBar.radar" = "radar"; "tabBar.radar" = "radar";
"tabBar.menu" = "menu"; "tabBar.menu" = "menu";
//Menu
"menu.goPremium" = "Go premium";
"menu.premium.desc" = "Experience app without ads @ $8.99 a year";
"menu.tv" = "1Weather TV";
"menu.radar" = "Radar";
"menu.buyNow" = "Buy now";
"menu.settings" = "Settings";
"menu.about" = "About us";
"menu.ad" = "Ad choices";
"menu.rateUs" = "Rate us";
"menu.help" = "Help";
"menu.faq" = "FAQ's";
"menu.privacy" = "Privacy Policy";
"menu.version" = "version";
//
// MenuCell.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuCell: UITableViewCell {
//Private
private let container = UIView()
private let typeImageView = UIImageView()
private let typeLabel = UILabel()
private let arrowLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
prepareCell()
prepareContainer()
prepareImageView()
prepareLabel()
prepareArrowLabel()
updateUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateUI()
}
//Public
public func configure(image:UIImage?, text:String, roundendCorners:CACornerMask) {
self.typeImageView.image = image
self.typeLabel.text = text
if roundendCorners.isEmpty {
self.container.layer.cornerRadius = 0
self.container.layer.maskedCorners = []
}
else {
self.container.layer.cornerRadius = 12
self.container.layer.maskedCorners = roundendCorners
}
}
//Private
private func updateUI() {
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
switch interfaceStyle {
case .light:
arrowLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
typeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
typeImageView.tintColor = ThemeManager.currentTheme.secondaryTextColor
self.tintColor = ThemeManager.currentTheme.secondaryTextColor
case .dark:
arrowLabel.textColor = ThemeManager.currentTheme.primaryTextColor
typeLabel.textColor = ThemeManager.currentTheme.primaryTextColor
typeImageView.tintColor = ThemeManager.currentTheme.primaryTextColor
self.tintColor = ThemeManager.currentTheme.primaryTextColor
}
}
}
//MARK:- Prepare
private extension MenuCell {
func prepareCell() {
selectionStyle = .none
}
func prepareContainer() {
contentView.addSubview(container)
container.snp.makeConstraints { (make) in
make.left.right.equalToSuperview().inset(18)
make.top.bottom.equalToSuperview()
}
}
func prepareImageView() {
typeImageView.contentMode = .scaleAspectFit
container.addSubview(typeImageView)
typeImageView.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(15)
make.centerY.equalToSuperview()
make.width.height.equalTo(17)
}
}
func prepareLabel() {
typeLabel.font = AppFont.SFPro.regular(size: 16)
typeLabel.textAlignment = .left
container.addSubview(typeLabel)
typeLabel.snp.makeConstraints { (make) in
make.left.equalTo(typeImageView.snp.right).offset(15)
make.centerY.equalToSuperview()
}
}
func prepareArrowLabel() {
arrowLabel.text = "􀆊"
arrowLabel.font = AppFont.SFPro.regular(size: 16)
arrowLabel.textAlignment = .right
container.addSubview(arrowLabel)
arrowLabel.snp.makeConstraints { (make) in
make.right.equalToSuperview().inset(18)
make.centerY.equalToSuperview()
}
}
}
//
// MenuCellFactory.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
private enum Section {
case settings
case info
}
private enum Row: String {
case settings
case about
case ad
case rateUs
case help
case faq
case privacy
var image: UIImage? {
switch self {
case .settings:
return UIImage(named: "menu_settings")
case .about:
return UIImage(named: "menu_about")
case .ad:
return UIImage(named: "menu_ad")
case .rateUs:
return UIImage(named: "menu_rateUs")
case .help:
return UIImage(named: "menu_help")
case .faq:
return UIImage(named: "menu_faq")
case .privacy:
return UIImage(named: "menu_privacyPolicy")
}
}
var localized: String {
switch self {
case .settings:
return "menu.settings".localized()
case .about:
return "menu.about".localized()
case .ad:
return "menu.ad".localized()
case .rateUs:
return "menu.rateUs".localized()
case .help:
return "menu.help".localized()
case .faq:
return "menu.faq".localized()
case .privacy:
return "menu.privacy".localized()
}
}
var roundedCorners:CACornerMask {
switch self {
case .settings:
return [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
case .about:
return [.layerMinXMinYCorner, .layerMaxXMinYCorner]
case .ad:
return []
case .rateUs:
return []
case .help:
return []
case .faq:
return []
case .privacy:
return [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
}
}
}
private struct SectionItem {
let rows:[Row]
}
class MenuCellFactory {
//Private
private let menuViewModel:MenuViewModel
private let sections:[SectionItem] = [SectionItem(rows: [.settings]),
SectionItem(rows: [.about, .ad, .rateUs, .help, .faq, .privacy])]
//Public
static let kSectionHeight:CGFloat = 30
static let kRowHeight:CGFloat = 57
public var numberOfSections:Int {
return sections.count
}
init(viewModel: MenuViewModel) {
self.menuViewModel = viewModel
}
public func numberOfRows(inSection section:Int) -> Int {
switch section {
case 0:
return sections[0].rows.count
case 1:
return sections[1].rows.count
case 2:
return sections[2].rows.count
default:
return 0
}
}
public func registerCells(on tableView:UITableView) {
registerCell(type: MenuCell.self, tableView: tableView)
}
public func cellFromTableView(tableView:UITableView, indexPath:IndexPath) -> UITableViewCell {
let cellType = sections[indexPath.section].rows[indexPath.row]
let cell = dequeueReusableCell(type: MenuCell.self, tableView: tableView, indexPath: indexPath)
cell.configure(image: cellType.image,
text: cellType.localized,
roundendCorners: cellType.roundedCorners)
return cell
}
private func registerCell<T: ReusableCellProtocol>(type:T.Type, tableView:UITableView) {
tableView.register(type, forCellReuseIdentifier: T.kIdentifier)
}
private func dequeueReusableCell<T: ReusableCellProtocol>(type:T.Type, tableView:UITableView, indexPath: IndexPath) -> T {
let cell = tableView.dequeueReusableCell(withIdentifier: T.kIdentifier, for: indexPath) as! T
return cell
}
}
//
// MenuFooterView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuFooterView: UIView {
//Private
private let appImageView = UIImageView()
private let appNameLabel = UILabel()
private let versionLabel = UILabel()
private var appVersion:String {
if let infoDict: [String:Any] = Bundle.main.infoDictionary {
let appVersion = infoDict["CFBundleShortVersionString"] as? String
return "\("menu.version".localized().capitalized) \(appVersion ?? "--")"
}
return "N/A"
}
init() {
super.init(frame: .zero)
prepareAppImageView()
prepareLabels()
updateUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func updateUI() {
backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
switch interfaceStyle {
case .light:
appNameLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
versionLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
case .dark:
appNameLabel.textColor = ThemeManager.currentTheme.primaryTextColor
versionLabel.textColor = ThemeManager.currentTheme.primaryTextColor
}
}
}
//MARK:- Prepare
private extension MenuFooterView {
func prepareAppImageView() {
appImageView.contentMode = .scaleAspectFit
appImageView.image = UIImage(named: "version_icon")
addSubview(appImageView)
appImageView.snp.makeConstraints { (make) in
make.width.height.equalTo(40)
make.top.equalToSuperview().inset(30).priority(999)
make.left.equalToSuperview().inset(18)
make.bottom.equalToSuperview()
}
}
func prepareLabels() {
appNameLabel.font = AppFont.SFPro.bold(size: 18)
appNameLabel.text = Bundle.main.infoDictionary?[kCFBundleNameKey as String] as? String
addSubview(appNameLabel)
versionLabel.textAlignment = .right
versionLabel.font = AppFont.SFPro.regular(size: 14)
versionLabel.text = appVersion
addSubview(versionLabel)
//Constraints
appNameLabel.snp.makeConstraints { (make) in
make.left.equalTo(appImageView.snp.right).offset(18)
make.centerY.equalTo(appImageView)
}
versionLabel.snp.makeConstraints { (make) in
make.right.equalToSuperview().inset(18)
make.centerY.equalTo(appImageView)
}
}
}
//
// MenuBuyButton.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuBuyButton: UIControl {
//Private
private let label = UILabel()
private let gradient = CAGradientLayer()
override init(frame: CGRect) {
super.init(frame: frame)
prepareButton()
prepareGradient()
prepareLabel()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
gradient.frame = self.bounds
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
UIView.performWithoutAnimation {
self.alpha = 0.7
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
UIView.performWithoutAnimation {
self.alpha = 1
}
}
}
//MARK:- Prepare
private extension MenuBuyButton {
func prepareButton() {
layer.cornerRadius = 4
}
func prepareGradient() {
gradient.cornerRadius = self.layer.cornerRadius
gradient.frame = self.bounds
gradient.colors = [UIColor(hex: 0x5e77ff).cgColor, UIColor(hex: 0x97abf4).cgColor]
gradient.startPoint = .init(x: 0, y: 0.5)
gradient.endPoint = .init(x: 1, y: 0.5)
layer.addSublayer(gradient)
}
func prepareLabel() {
label.textColor = .white
label.font = AppFont.SFPro.regular(size: 18)
label.text = "menu.buyNow".localized()
label.setContentHuggingPriority(.fittingSizeLevel, for: .vertical)
addSubview(label)
label.snp.makeConstraints { (make) in
make.top.bottom.equalToSuperview().inset(8).priority(.init(999))
make.left.right.equalToSuperview().inset(12)
}
}
}
//
// MenuHeaderButton.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuHeaderButton: UIControl {
//Private
private let imageView = UIImageView()
private let label = UILabel()
init(image:UIImage?, text:String) {
super.init(frame: .zero)
self.imageView.image = image
self.label.text = text
prepareButton()
prepareImageView()
prepareLabel()
updateUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
UIView.performWithoutAnimation {
self.alpha = 0.7
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
UIView.performWithoutAnimation {
self.alpha = 1
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateUI()
}
//Private
private func updateUI() {
backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
switch interfaceStyle {
case .light:
label.textColor = ThemeManager.currentTheme.secondaryTextColor
case .dark:
label.textColor = ThemeManager.currentTheme.primaryTextColor
}
}
}
//MARK:- Prepare
private extension MenuHeaderButton {
func prepareButton() {
layer.cornerRadius = 12
}
func prepareImageView() {
imageView.isUserInteractionEnabled = false
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
imageView.snp.makeConstraints { (make) in
make.top.equalToSuperview().inset(24)
make.width.height.equalTo(32)
make.centerX.equalToSuperview()
}
}
func prepareLabel() {
label.isUserInteractionEnabled = false
label.font = AppFont.SFPro.bold(size: 18)
label.textAlignment = .center
label.setContentHuggingPriority(.fittingSizeLevel, for: .vertical)
addSubview(label)
label.snp.makeConstraints { (make) in
make.top.equalTo(imageView.snp.bottom).offset(12).priority(.init(floatLiteral: 999))
make.left.right.equalToSuperview()
make.bottom.equalToSuperview().inset(24)
}
}
}
//
// MenuHeaderView.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuHeaderView: UIView {
//Private
private let premiumContainer = UIView()
private let premiumHeadingLabel = UILabel()
private let premiumDescriptionLabel = UILabel()
private let buyButton = MenuBuyButton()
private let premiumImageView = UIImageView()
private let tvButton = MenuHeaderButton(image: UIImage(named: "menu_tv"), text: "menu.tv".localized())
private let radarButton = MenuHeaderButton(image: UIImage(named: "menu_radar"), text: "menu.radar".localized())
init() {
super.init(frame: .zero)
prepareView()
preparePremium()
prepareButtons()
updateUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateUI()
}
//Prvaite
private func updateUI() {
backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
premiumContainer.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
premiumHeadingLabel.textColor = ThemeManager.currentTheme.primaryTextColor
premiumDescriptionLabel.textColor = ThemeManager.currentTheme.primaryTextColor
switch interfaceStyle {
case .light:
premiumContainer.layer.shadowColor = UIColor(hex: 0x020116).cgColor
premiumContainer.layer.shadowOffset = .init(width: 0, height: 10)
premiumContainer.layer.shadowRadius = 20
premiumContainer.layer.shadowOpacity = 0.12
case .dark:
premiumContainer.layer.shadowColor = UIColor.black.cgColor
premiumContainer.layer.shadowOffset = .init(width: 8, height: 8)
premiumContainer.layer.shadowRadius = 8
premiumContainer.layer.shadowOpacity = 1.0
}
}
@objc private func handleBuyButton() {
}
@objc private func handleButton(button:MenuHeaderButton) {
}
}
//MARK:- Prepare
private extension MenuHeaderView {
func prepareView() {
backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
}
func preparePremium() {
premiumContainer.layer.cornerRadius = 12
addSubview(premiumContainer)
premiumHeadingLabel.font = AppFont.SFPro.bold(size: 34)
premiumHeadingLabel.text = "menu.goPremium".localized()
premiumHeadingLabel.setContentHuggingPriority(.fittingSizeLevel, for: .vertical)
premiumContainer.addSubview(premiumHeadingLabel)
premiumDescriptionLabel.lineBreakMode = .byWordWrapping
premiumDescriptionLabel.numberOfLines = 0
premiumDescriptionLabel.font = AppFont.SFPro.regular(size: 16)
premiumDescriptionLabel.text = "menu.premium.desc".localized()
premiumDescriptionLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
premiumContainer.addSubview(premiumDescriptionLabel)
buyButton.addTarget(self, action: #selector(handleBuyButton), for: .touchUpInside)
premiumContainer.addSubview(buyButton)
premiumImageView.contentMode = .scaleAspectFit
premiumImageView.image = UIImage(named: "premium")
premiumContainer.addSubview(premiumImageView)
//Constraints
premiumContainer.snp.makeConstraints { (make) in
make.top.equalTo(30)
make.left.right.equalToSuperview().inset(18).priority(999)
}
premiumImageView.snp.makeConstraints { (make) in
make.width.height.equalTo(140)
make.right.bottom.equalToSuperview()
}
premiumHeadingLabel.snp.makeConstraints { (make) in
make.left.top.equalToSuperview().inset(18)
}
premiumDescriptionLabel.snp.makeConstraints { (make) in
make.left.equalToSuperview().inset(18)
make.top.equalTo(premiumHeadingLabel.snp.bottom)
make.right.equalTo(premiumImageView.snp.left)
}
buyButton.snp.makeConstraints { (make) in
make.top.equalTo(premiumDescriptionLabel.snp.bottom).offset(18).priority(999)
make.left.equalToSuperview().inset(18)
make.bottom.equalToSuperview().inset(24)
}
}
func prepareButtons() {
tvButton.addTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside)
addSubview(tvButton)
radarButton.addTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside)
addSubview(radarButton)
//Constraints
tvButton.snp.makeConstraints { (make) in
make.left.equalTo(premiumContainer)
make.top.equalTo(premiumContainer.snp.bottom).offset(30).priority(999)
make.width.equalTo(165)
make.bottom.equalToSuperview().inset(30)
}
radarButton.snp.makeConstraints { (make) in
make.right.equalTo(premiumContainer)
make.top.equalTo(premiumContainer.snp.bottom).offset(30).priority(999)
make.width.equalTo(165)
make.bottom.equalToSuperview().inset(30)
}
}
}
//
// MenuViewController.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuViewController: UIViewController {
//Private
private let viewModel:MenuViewModel
private let menuHeaderView = MenuHeaderView()
private let menuCellFactory:MenuCellFactory
private let tableView = UITableView()
init(menuViewModel: MenuViewModel) {
self.viewModel = menuViewModel
self.menuCellFactory = MenuCellFactory(viewModel: menuViewModel)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
prepareController()
prepareTableView()
updateUI()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.layoutTableHeaderView()
tableView.layoutTableFooterView()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateUI()
}
private func updateUI() {
view.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
tableView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
}
}
//MARK:- Prepare
private extension MenuViewController {
func prepareController() {
navigationController?.setNavigationBarHidden(true, animated: false)
}
func prepareTableView() {
menuCellFactory.registerCells(on: tableView)
tableView.showsVerticalScrollIndicator = false
tableView.showsHorizontalScrollIndicator = false
tableView.separatorStyle = .none
tableView.dataSource = self
tableView.delegate = self
tableView.rowHeight = MenuCellFactory.kRowHeight
tableView.tableFooterView = UIView()
tableView.tableHeaderView = menuHeaderView
tableView.tableFooterView = MenuFooterView()
tableView.contentInset = .init(top: 0, left: 0, bottom: 30, right: 0)
view.addSubview(tableView)
tableView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
}
}
//MARK:- UITableView Data Source
extension MenuViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuCellFactory.numberOfRows(inSection: section)
}
func numberOfSections(in tableView: UITableView) -> Int {
return menuCellFactory.numberOfSections
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return menuCellFactory.cellFromTableView(tableView: tableView, indexPath: indexPath)
}
}
//MARK:- UITableView Delegate
extension MenuViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return 0
}
return MenuCellFactory.kSectionHeight
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
return view
}
}
...@@ -56,20 +56,16 @@ class CityForecastCell: UITableViewCell { ...@@ -56,20 +56,16 @@ class CityForecastCell: UITableViewCell {
temperatureLabel.textColor = ThemeManager.currentTheme.primaryTextColor temperatureLabel.textColor = ThemeManager.currentTheme.primaryTextColor
forecastDescriptionLabel.textColor = ThemeManager.currentTheme.primaryTextColor forecastDescriptionLabel.textColor = ThemeManager.currentTheme.primaryTextColor
feelsLikeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor feelsLikeLabel.textColor = ThemeManager.currentTheme.secondaryTextColor
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
switch interfaceStyle { switch interfaceStyle {
case .light: case .light:
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
container.layer.shadowColor = UIColor(hex: 0x020116).cgColor container.layer.shadowColor = UIColor(hex: 0x020116).cgColor
container.layer.shadowOffset = .init(width: 0, height: 10) container.layer.shadowOffset = .init(width: 0, height: 10)
container.layer.shadowRadius = 20 container.layer.shadowRadius = 20
container.layer.shadowOpacity = 0.12 container.layer.shadowOpacity = 0.12
case .dark: case .dark:
contentView.backgroundColor = ThemeManager.currentTheme.baseBackgroundColor
container.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
container.layer.shadowColor = UIColor.black.cgColor container.layer.shadowColor = UIColor.black.cgColor
container.layer.shadowOffset = .init(width: 8, height: 8) container.layer.shadowOffset = .init(width: 8, height: 8)
container.layer.shadowRadius = 8 container.layer.shadowRadius = 8
......
//
// MenuViewModel.swift
// 1Weather
//
// Created by Dmitry Stepanets on 25.03.2021.
//
import UIKit
class MenuViewModel: ViewModelProtocol {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment