Commit 92fda9d3 by Dmitriy Stepanets

Added sync between DayControlsButton and ForecastTimePeriodCell

parent bbf41fed
......@@ -7,7 +7,7 @@
<key>1Weather.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>5</integer>
</dict>
<key>PG (Playground) 1.xcscheme</key>
<dict>
......
......@@ -60,9 +60,23 @@ class ForecastTimePeriodView: UIView {
}
}
public func set(timePeriod:TimePeriod, buttonType: PeriodButtonProtocol.Type, selectedIndex:Int = 0) {
public func set(timePeriod:TimePeriod, buttonType: PeriodButtonProtocol.Type) {
self.currentTimePeriod = timePeriod
rebuildButtons(buttonType: buttonType, selectedIndex: selectedIndex)
rebuildButtons(buttonType: buttonType)
}
public func selectButtonAt(index:Int) {
guard let buttons = self.stackView.arrangedSubviews as? [PeriodButtonProtocol] else {
return
}
buttons.enumerated().forEach {
$1.isSelected = $0 == index
if $1.isSelected {
self.scrollView.scrollRectToVisible($1.frame, animated: true)
}
}
}
//Private
......@@ -79,7 +93,7 @@ class ForecastTimePeriodView: UIView {
}
}
private func rebuildButtons(buttonType: PeriodButtonProtocol.Type, selectedIndex:Int) {
private func rebuildButtons(buttonType: PeriodButtonProtocol.Type) {
stackView.removeAll()
let numberOfButtons:Int
......@@ -100,7 +114,7 @@ class ForecastTimePeriodView: UIView {
}
forecastButton.index = index
forecastButton.addTarget(self, action: #selector(handleForecastButton(button:)), for: .touchUpInside)
forecastButton.isSelected = index == selectedIndex
forecastButton.isSelected = index == 0
stackView.addArrangedSubview(forecastButton)
forecastButton.snp.makeConstraints { (make) in
......
......@@ -47,6 +47,7 @@ class ForecastCellFactory {
case .forecastPeriod:
let cell = dequeueReusableCell(type: ForecastTimePeriodCell.self, tableView: tableView, indexPath: indexPath)
cell.delegate = self
cell.selectDayButtonAt(index: forecastViewModel.selectedDailyWeatherIndex)
if let daily = forecastViewModel.location?.daily,
let hourly = forecastViewModel.location?.hourly {
......@@ -100,6 +101,11 @@ class ForecastCellFactory {
//MARK:- ForecastTimePeriodCell Delegate
extension ForecastCellFactory: ForecastTimePeriodCellDelegate {
func timePeriodCell(cell: ForecastTimePeriodCell, didSelectButtonAt index: Int) {
guard forecastViewModel.currentTimePeriod == .daily else { return }
forecastViewModel.selectDailyWeather(at: index)
}
func timePeriodCell(cell: ForecastTimePeriodCell, didSelectTimePeriod timePeriod: TimePeriod) {
forecastViewModel.setTimePeriod(timePeriod: timePeriod)
}
}
......@@ -9,6 +9,7 @@ import UIKit
protocol ForecastTimePeriodCellDelegate:class {
func timePeriodCell(cell:ForecastTimePeriodCell, didSelectButtonAt index:Int)
func timePeriodCell(cell:ForecastTimePeriodCell, didSelectTimePeriod timePeriod:TimePeriod)
}
class ForecastTimePeriodCell: UITableViewCell {
......@@ -48,6 +49,10 @@ class ForecastTimePeriodCell: UITableViewCell {
}
}
public func selectDayButtonAt(index:Int) {
self.forecastTimePeriodView.selectButtonAt(index: index)
}
@objc private func handleSegmentDidChange() {
guard let timePeriod = TimePeriod(rawValue: self.periodSegmentedControl.selectedSegmentIndex) else {
return
......@@ -59,6 +64,8 @@ class ForecastTimePeriodCell: UITableViewCell {
case .hourly:
self.forecastTimePeriodView.set(timePeriod: timePeriod, buttonType: ForecastPeriodButton.self)
}
delegate?.timePeriodCell(cell: self, didSelectTimePeriod: timePeriod)
}
}
......
......@@ -7,6 +7,10 @@
import UIKit
protocol DaysControlViewDelegate:class {
func didSelectButtonAt(index:Int)
}
class DaysControlView: UIView {
//Private
private let scrollView = UIScrollView()
......@@ -14,10 +18,14 @@ class DaysControlView: UIView {
private let gradientView = GradientView(startColor:UIColor(hex: 0xffffff).withAlphaComponent(0),
endColor: UIColor(hex: 0xdaddec),
opacity: 0.5)
//Public
weak var delegate:DaysControlViewDelegate?
private var statusBarHeight: CGFloat {
var statusBarHeight: CGFloat = 0
if #available(iOS 13.0, *) {
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
let window = UIApplication.shared.windows.filter{ $0.isKeyWindow }.first
statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
} else {
statusBarHeight = UIApplication.shared.statusBarFrame.height
......@@ -39,10 +47,7 @@ class DaysControlView: UIView {
}
public func configure(dailyWeather: [DailyWeather]) {
stackView.arrangedSubviews.forEach {
stackView.removeArrangedSubview($0)
$0.removeFromSuperview()
}
stackView.removeAll()
for index in 0..<dailyWeather.count {
let button = DayControlButton()
......@@ -54,11 +59,29 @@ class DaysControlView: UIView {
stackView.layoutIfNeeded()
}
public func selectDayAt(index:Int) {
guard let buttons = stackView.arrangedSubviews as? [DayControlButton] else {
return
}
buttons.enumerated().forEach {
$1.isSelected = $0 == index
if $1.isSelected {
scrollView.scrollRectToVisible($1.frame, animated: true)
}
}
}
@objc private func handleDayButton(button:DayControlButton) {
guard let buttons = stackView.arrangedSubviews as? [DayControlButton] else { return }
buttons.forEach {
$0.isSelected = $0 === button
buttons.enumerated().forEach {
$1.isSelected = $1 === button
if $1.isSelected {
self.delegate?.didSelectButtonAt(index: $0)
}
}
}
}
......@@ -80,7 +103,7 @@ private extension DaysControlView {
addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
make.top.equalToSuperview().inset(statusBarHeight + 22)
make.top.equalToSuperview().inset(statusBarHeight)
make.left.right.equalToSuperview()
make.bottom.equalToSuperview().inset(18)
make.height.greaterThanOrEqualTo(50)
......@@ -94,7 +117,7 @@ private extension DaysControlView {
stackView.spacing = 10
stackView.clipsToBounds = false
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = .init(top: 0, left: 10, bottom: 0, right: 10)
stackView.layoutMargins = .init(top: 0, left: 6, bottom: 0, right: 6)
scrollView.addSubview(stackView)
stackView.snp.makeConstraints { (make) in
......
......@@ -36,7 +36,9 @@ class ForecastViewController: UIViewController {
prepareNavigationBar()
prepareTableView()
prepareDayControlsView()
refreshCityButton()
refreshDayButtons()
}
private func refreshCityButton() {
......@@ -44,6 +46,15 @@ class ForecastViewController: UIViewController {
cityButton.isHidden = false
}
private func refreshDayButtons() {
if let dailyWeather = viewModel.location?.daily {
daysControlView.configure(dailyWeather: dailyWeather)
}
else {
daysControlView.alpha = 0
}
}
@objc private func handleCityButton() {
print("Handle city button")
}
......@@ -87,6 +98,7 @@ private extension ForecastViewController {
func prepareDayControlsView() {
daysControlView.alpha = 0
daysControlView.delegate = self
view.addSubview(daysControlView)
daysControlView.snp.makeConstraints { (make) in
make.top.left.right.equalToSuperview()
......@@ -116,7 +128,8 @@ extension ForecastViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard
let navVC = self.navigationController,
viewModel.location?.daily.isEmpty == false
viewModel.location?.daily.isEmpty == false,
viewModel.currentTimePeriod == .daily
else {
return
}
......@@ -167,13 +180,7 @@ extension ForecastViewController: ForecastViewModelDelegate {
func viewModelDidChange<P>(model: P) where P : ViewModelProtocol {
refreshCityButton()
tableView.reloadData()
if let dailyWeather = viewModel.location?.daily {
daysControlView.configure(dailyWeather: dailyWeather)
}
else {
daysControlView.alpha = 0
}
refreshDayButtons()
}
func selectedDailyWeatherDidChange() {
......@@ -185,5 +192,21 @@ extension ForecastViewController: ForecastViewModelDelegate {
}
tableView.reloadRows(at: indexPathToReload, with: .none)
daysControlView.selectDayAt(index: viewModel.selectedDailyWeatherIndex)
}
func selectedTimePeriodDidChange() {
guard let timePeriodCell = tableView.cellForRow(at: [0,0]) as? ForecastTimePeriodCell else {
return
}
timePeriodCell.selectDayButtonAt(index: viewModel.selectedDailyWeatherIndex)
}
}
//MARK:- DaysControlView Delegate
extension ForecastViewController: DaysControlViewDelegate {
func didSelectButtonAt(index: Int) {
viewModel.selectDailyWeather(at: index)
}
}
......@@ -9,6 +9,7 @@ import UIKit
protocol ForecastViewModelDelegate:ViewModelDelegate {
func selectedDailyWeatherDidChange()
func selectedTimePeriodDidChange()
}
class ForecastViewModel: ViewModelProtocol {
......@@ -16,6 +17,18 @@ class ForecastViewModel: ViewModelProtocol {
public weak var delegate:ForecastViewModelDelegate?
public private(set) var location: Location?
public private(set) var selectedDailyWeather:DailyWeather?
public private(set) var currentTimePeriod = TimePeriod.daily
public var selectedDailyWeatherIndex:Int {
guard let loc = self.location else { return -1 }
for (index, day) in loc.daily.enumerated() {
if day == selectedDailyWeather {
return index
}
}
return -1
}
//Private
private var locationManager: LocationManager
......@@ -47,6 +60,11 @@ class ForecastViewModel: ViewModelProtocol {
}
self.delegate?.selectedDailyWeatherDidChange()
}
public func setTimePeriod(timePeriod:TimePeriod) {
self.currentTimePeriod = timePeriod
self.delegate?.selectedTimePeriodDidChange()
}
}
//MARK:- LocationManager Delegate
......
......@@ -40,14 +40,14 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
<key>SnapKit.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>3</integer>
</dict>
<key>XMLCoder.xcscheme_^#shared#^_</key>
<dict>
......
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