Commit 637f28d0 by Dmitriy Stepanets

some work

parent ce879c83
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
CD1237DE255D612300C98139 /* CurrentForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237DD255D612300C98139 /* CurrentForecastCell.swift */; }; CD1237DE255D612300C98139 /* CurrentForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237DD255D612300C98139 /* CurrentForecastCell.swift */; };
CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237F0255D83C500C98139 /* UIColor+Hex.swift */; }; CD1237F1255D83C500C98139 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237F0255D83C500C98139 /* UIColor+Hex.swift */; };
CD1237F4255D889F00C98139 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237F3255D889F00C98139 /* GradientView.swift */; }; CD1237F4255D889F00C98139 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1237F3255D889F00C98139 /* GradientView.swift */; };
CD578DE3257A42F200ECCBC3 /* InitialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD578DE2257A42F200ECCBC3 /* InitialViewController.swift */; };
CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B3035257262C2004B34B3 /* UIColor+Highlight.swift */; }; CD6B3036257262C2004B34B3 /* UIColor+Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B3035257262C2004B34B3 /* UIColor+Highlight.swift */; };
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303A2572680C004B34B3 /* SelfSizingButton.swift */; }; CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303A2572680C004B34B3 /* SelfSizingButton.swift */; };
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303D25726960004B34B3 /* ThemeProtocol.swift */; }; CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6B303D25726960004B34B3 /* ThemeProtocol.swift */; };
...@@ -55,6 +56,7 @@ ...@@ -55,6 +56,7 @@
CD1237DD255D612300C98139 /* CurrentForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentForecastCell.swift; sourceTree = "<group>"; }; CD1237DD255D612300C98139 /* CurrentForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentForecastCell.swift; sourceTree = "<group>"; };
CD1237F0255D83C500C98139 /* UIColor+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = "<group>"; }; CD1237F0255D83C500C98139 /* UIColor+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = "<group>"; };
CD1237F3255D889F00C98139 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; }; CD1237F3255D889F00C98139 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
CD578DE2257A42F200ECCBC3 /* InitialViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialViewController.swift; sourceTree = "<group>"; };
CD6B3035257262C2004B34B3 /* UIColor+Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Highlight.swift"; sourceTree = "<group>"; }; CD6B3035257262C2004B34B3 /* UIColor+Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Highlight.swift"; sourceTree = "<group>"; };
CD6B303A2572680C004B34B3 /* SelfSizingButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelfSizingButton.swift; sourceTree = "<group>"; }; CD6B303A2572680C004B34B3 /* SelfSizingButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelfSizingButton.swift; sourceTree = "<group>"; };
CD6B303D25726960004B34B3 /* ThemeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeProtocol.swift; sourceTree = "<group>"; }; CD6B303D25726960004B34B3 /* ThemeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeProtocol.swift; sourceTree = "<group>"; };
...@@ -125,6 +127,7 @@ ...@@ -125,6 +127,7 @@
CD1237CD255D5C5C00C98139 /* LaunchScreen.storyboard */, CD1237CD255D5C5C00C98139 /* LaunchScreen.storyboard */,
CD1237D0255D5C5C00C98139 /* Info.plist */, CD1237D0255D5C5C00C98139 /* Info.plist */,
CEAD00A02577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift */, CEAD00A02577B2D5003596AD /* StuffThatIsPresentInTheMainProject.swift */,
CD578DE2257A42F200ECCBC3 /* InitialViewController.swift */,
); );
path = 1Weather; path = 1Weather;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -394,6 +397,7 @@ ...@@ -394,6 +397,7 @@
CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */, CD6B303E25726960004B34B3 /* ThemeProtocol.swift in Sources */,
CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */, CD6B303B2572680C004B34B3 /* SelfSizingButton.swift in Sources */,
CD8091772578D73F003541A4 /* PopularCitiesManager.swift in Sources */, CD8091772578D73F003541A4 /* PopularCitiesManager.swift in Sources */,
CD578DE3257A42F200ECCBC3 /* InitialViewController.swift in Sources */,
CDA69B2C2574F3C800CB6409 /* CityCell.swift in Sources */, CDA69B2C2574F3C800CB6409 /* CityCell.swift in Sources */,
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */, CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */,
CD1237DE255D612300C98139 /* CurrentForecastCell.swift in Sources */, CD1237DE255D612300C98139 /* CurrentForecastCell.swift in Sources */,
......
...@@ -16,7 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -16,7 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
ThemeManager.refreshAppearance() ThemeManager.refreshAppearance()
self.window = UIWindow(frame: UIScreen.main.bounds) self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = LocationViewController() self.window?.rootViewController = InitialViewController()
self.window?.makeKeyAndVisible() self.window?.makeKeyAndVisible()
return true return true
......
//
// InitialViewController.swift
// 1Weather
//
// Created by Dmitry Stepanets on 04.12.2020.
//
import UIKit
class InitialViewController: UIViewController {
let searchButton = SelfSizingButton()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
prepareSearchButton()
}
@objc private func handleSearchButton() {
let locationVC = LocationViewController(closeButtonIsHidden: false)
self.present(locationVC, animated: true)
}
}
//MARK:- Prepare
private extension InitialViewController {
func prepareSearchButton() {
searchButton.setTitle("Open Search controller", for: .normal)
searchButton.setTitleColor(.black, for: .normal)
searchButton.backgroundColor = .lightGray
searchButton.addTarget(self, action: #selector(handleSearchButton), for: .touchUpInside)
searchButton.titleEdgeInsets = .init(top: 0, left: 16, bottom: 0, right: 16)
view.addSubview(searchButton)
searchButton.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalToSuperview().inset(100)
}
}
}
{
"images" : [
{
"filename" : "city_checkmark.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "close-cross.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "dot.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "edit_pencil.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
{
"images" : [
{
"filename" : "location_arrow.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "original"
}
}
...@@ -9,6 +9,7 @@ import UIKit ...@@ -9,6 +9,7 @@ import UIKit
public struct ThemeManager { public struct ThemeManager {
struct Colors { struct Colors {
static let
static let locationBlue = UIColor(hex: 0x1071F0) static let locationBlue = UIColor(hex: 0x1071F0)
static let temperatureLabelBG = UIColor(hex: 0x5F5F5F) static let temperatureLabelBG = UIColor(hex: 0x5F5F5F)
static let citySelected = UIColor(hex: 0x599A0E) static let citySelected = UIColor(hex: 0x599A0E)
......
...@@ -9,21 +9,10 @@ import UIKit ...@@ -9,21 +9,10 @@ import UIKit
//MARK:- Location Navigation View Controller //MARK:- Location Navigation View Controller
class LocationViewController: UINavigationController { class LocationViewController: UINavigationController {
init() { init(closeButtonIsHidden:Bool = false) {
let savedCitiesViewController = CitiesViewController() let savedCitiesViewController = CitiesViewController(closeButtonHidden: closeButtonIsHidden)
super.init(rootViewController: savedCitiesViewController) super.init(rootViewController: savedCitiesViewController)
} self.modalPresentationStyle = .fullScreen
override convenience init(rootViewController: UIViewController) {
self.init()
}
override convenience init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
self.init()
}
override convenience init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
self.init()
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
...@@ -51,6 +40,15 @@ private class CitiesViewController:UIViewController { ...@@ -51,6 +40,15 @@ private class CitiesViewController:UIViewController {
return queue return queue
}() }()
init(closeButtonHidden:Bool = false) {
super.init(nibName: nil, bundle: nil)
prepareNavBar(closeButtonIsHidden: closeButtonHidden)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -58,13 +56,25 @@ private class CitiesViewController:UIViewController { ...@@ -58,13 +56,25 @@ private class CitiesViewController:UIViewController {
edgesForExtendedLayout = [] edgesForExtendedLayout = []
self.locationsViewModel.delegate = self self.locationsViewModel.delegate = self
prepareNavBar()
prepareSearchBar() prepareSearchBar()
prepareLocationButton() prepareLocationButton()
prepareTableView() prepareTableView()
prepareEditButton() prepareEditButton()
} }
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//Update navigation title view constraints
guard let containerView = self.navigationItem.titleView?.superview else { return }
self.navigationItem.titleView?.snp.remakeConstraints({ (make) in
make.left.equalTo(containerView).inset(24).priority(.medium)
make.top.equalTo(containerView).priority(.medium)
make.right.equalTo(containerView).priority(.medium)
make.bottom.equalTo(containerView).priority(.medium)
})
}
private func updateEditButton(style:EditButtonStyle) { private func updateEditButton(style:EditButtonStyle) {
switch style { switch style {
case .edit: case .edit:
...@@ -96,7 +106,7 @@ private class CitiesViewController:UIViewController { ...@@ -96,7 +106,7 @@ private class CitiesViewController:UIViewController {
//MARK:- Saved cities prepare //MARK:- Saved cities prepare
private extension CitiesViewController { private extension CitiesViewController {
func prepareNavBar() { func prepareNavBar(closeButtonIsHidden:Bool) {
self.navigationController?.view.backgroundColor = .white self.navigationController?.view.backgroundColor = .white
//Title //Title
...@@ -108,20 +118,13 @@ private extension CitiesViewController { ...@@ -108,20 +118,13 @@ private extension CitiesViewController {
titleLabel.textColor = ThemeManager.currentTheme.navigationTintColor titleLabel.textColor = ThemeManager.currentTheme.navigationTintColor
navigationItem.titleView = titleLabel navigationItem.titleView = titleLabel
guard let containerView = self.navigationItem.titleView?.superview else { return } if !closeButtonIsHidden {
titleLabel.snp.makeConstraints({ (make) in
make.left.equalTo(containerView).inset(16).priority(.medium)
make.top.equalTo(containerView).priority(.medium)
make.right.equalTo(containerView).priority(.medium)
make.bottom.equalTo(containerView).priority(.medium)
})
//Close button //Close button
let closeButton = UIBarButtonItem(image: UIImage(named: "close_cross"), style: .plain, target: self, action: #selector(handleCloseButton)) let closeButton = UIBarButtonItem(image: UIImage(named: "close_cross"), style: .plain, target: self, action: #selector(handleCloseButton))
closeButton.tintColor = ThemeManager.currentTheme.navigationTintColor closeButton.tintColor = ThemeManager.currentTheme.navigationTintColor
self.navigationItem.rightBarButtonItems = [closeButton] self.navigationItem.rightBarButtonItems = [closeButton]
} }
}
func prepareSearchBar() { func prepareSearchBar() {
let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField
...@@ -196,11 +199,17 @@ extension CitiesViewController: LocationsViewModelDelegate { ...@@ -196,11 +199,17 @@ extension CitiesViewController: LocationsViewModelDelegate {
func viewModelDisplayModeDidChange(model: LocationsViewModel) { func viewModelDisplayModeDidChange(model: LocationsViewModel) {
DispatchQueue.main.async { DispatchQueue.main.async {
self.tableView.reloadData() self.tableView.reloadData()
if model.displayMode == .savedCities {
self.searchBar.text = nil
self.searchBar.endEditing(true)
self.searchBar.setShowsCancelButton(false, animated: true)
}
} }
} }
func viewModel(model: LocationsViewModel, errorHasOccured error: String?) { func viewModelError(model: LocationsViewModel, title: String?, message: String?) {
self.showAlert(withTitle: "Error", message: error) self.showAlert(withTitle: title, message: message)
} }
} }
......
...@@ -11,7 +11,7 @@ import AlgoliaSearchClient ...@@ -11,7 +11,7 @@ import AlgoliaSearchClient
protocol LocationsViewModelDelegate:class { protocol LocationsViewModelDelegate:class {
func viewModelDidChange(model:LocationsViewModel) func viewModelDidChange(model:LocationsViewModel)
func viewModelDisplayModeDidChange(model: LocationsViewModel) func viewModelDisplayModeDidChange(model: LocationsViewModel)
func viewModel(model:LocationsViewModel, errorHasOccured error: String?) func viewModelError(model:LocationsViewModel, title:String?, message:String?)
} }
enum LocationsViewModelDisplayMode { enum LocationsViewModelDisplayMode {
...@@ -73,7 +73,7 @@ class LocationsViewModel { ...@@ -73,7 +73,7 @@ class LocationsViewModel {
strongSelf.popularCities = popularCities.map{return WdtLocation(place: $0)} strongSelf.popularCities = popularCities.map{return WdtLocation(place: $0)}
} }
case .failure(let error): case .failure(let error):
strongSelf.delegate?.viewModel(model: strongSelf, errorHasOccured: error.localizedDescription) strongSelf.delegate?.viewModelError(model: strongSelf, title: "Error", message: error.localizedDescription)
} }
} }
} }
...@@ -143,7 +143,7 @@ class LocationsViewModel { ...@@ -143,7 +143,7 @@ class LocationsViewModel {
break break
case .failure(let error): case .failure(let error):
DispatchQueue.main.async { DispatchQueue.main.async {
strongSelf.delegate?.viewModel(model: strongSelf, errorHasOccured: error.localizedDescription) strongSelf.delegate?.viewModelError(model: strongSelf, title: "Error", message: error.localizedDescription)
} }
break break
} }
...@@ -153,14 +153,16 @@ class LocationsViewModel { ...@@ -153,14 +153,16 @@ class LocationsViewModel {
//MARK:- City CUD methods //MARK:- City CUD methods
func add(city:WdtLocation) { func add(city:WdtLocation) {
// TODO: Just update self.cities, it will trigger a viewModelDidChange call // TODO: Just update self.cities, it will trigger a viewModelDidChange call
if WeatherUpdateManager.shared.allLocationsCount >= 12 {
// let newCity = WdtLocation(zip: nil, city: "New City", region: "NS", countryCode: "US", country: "USA", lat: nil, lng: nil) self.delegate?.viewModelError(model: self, title: nil, message: "To keep your 1Weather running in tip-top shape, please limit the number of locations to 12.".localized)
return
}
if WeatherUpdateManager.shared.addLocation(city) { if WeatherUpdateManager.shared.addLocation(city) {
self.delegate?.viewModelDidChange(model: self) self.displayMode = .savedCities
} }
else { else {
self.delegate?.viewModel(model: self, errorHasOccured: "Failed to add location") self.delegate?.viewModelError(model: self, title: "Error", message: "Failed to add location")
} }
} }
...@@ -171,7 +173,7 @@ class LocationsViewModel { ...@@ -171,7 +173,7 @@ class LocationsViewModel {
self.delegate?.viewModelDidChange(model: self) self.delegate?.viewModelDidChange(model: self)
} }
else { else {
self.delegate?.viewModel(model: self, errorHasOccured: "Failed to delete location") self.delegate?.viewModelError(model: self, title: "Error", message: "Failed to delete location")
} }
} }
...@@ -182,7 +184,7 @@ class LocationsViewModel { ...@@ -182,7 +184,7 @@ class LocationsViewModel {
self.delegate?.viewModelDidChange(model: self) self.delegate?.viewModelDidChange(model: self)
} }
else { else {
self.delegate?.viewModel(model: self, errorHasOccured: "Failed to add location") self.delegate?.viewModelError(model: self, title: "Error", message: "Failed to add location")
} }
} }
} }
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