Skip to content

Commit d78bfe5

Browse files
committed
Bugfixes and the first result that can be called stable��
However, not all TODOs have been explained and solved
1 parent b4fa5b9 commit d78bfe5

7 files changed

Lines changed: 75 additions & 17 deletions

File tree

Source/DayView.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,20 @@ public final class DayView: UIView, TimelinePagerViewDelegate {
6161
}
6262

6363
public var calendar: Calendar = Calendar.autoupdatingCurrent {
64-
didSet {
65-
// TODO: Should we observe calendar in state rather then change it manualy?
64+
didSet { // TODO: willSet?
6665
dayHeaderView.calendar = self.calendar
6766
timelinePagerView.calendar = self.calendar
6867

69-
let date = self.state?.selectedDate ?? Date()
70-
let newState = DayViewState(date: date, calendar: calendar)
71-
newState.move(to: date)
72-
state = newState
68+
// recalculate the selectedDate taking into account
69+
// the difference between new and old timezones
70+
let oldCalendar = state!.calendar
71+
let selectedDate = (self.state?.selectedDate ?? Date())
72+
.dateOnly(calendar: calendar, oldCalendar: oldCalendar)
7373

74-
// TODO: Shound we redraw dayView and its subvies? Or we should do this when calendar in state was changed?
75-
// setNeedsDisplay()
76-
// self.subviews.forEach { $0.setNeedsDisplay() }
74+
// setting a new state
75+
let newState = DayViewState(date: selectedDate, calendar: calendar)
76+
state = newState
77+
newState.move(to: selectedDate) // TODO: Why I added this :I?
7778
}
7879
}
7980

Source/DayViewState.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public protocol DayViewStateUpdating: AnyObject {
66

77
public final class DayViewState {
88
public private(set) var calendar: Calendar
9+
// willSet {} // TODO: I think this needs to be implemented, cause timezone can change without creating a new state object
910
public private(set) var selectedDate: Date
1011
private var clients = [DayViewStateUpdating]()
1112

@@ -17,6 +18,7 @@ public final class DayViewState {
1718

1819
public func move(to date: Date) {
1920
let date = date.dateOnly(calendar: calendar)
21+
// if (date == selectedDate) { return } // TODO: If necessary? Just trying to make sure that willMoveTo not be called if we are already on this page
2022
notify(clients: clients, moveTo: date)
2123
selectedDate = date
2224
}

Source/Extensions/Date+DateOnly.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ extension Date {
1414
let returnValue = calendar.date(from: newComponents)
1515
return returnValue!
1616
}
17+
18+
/// Cuts off the time, leaving the beginning of the day for the new time zone
19+
func dateOnly(calendar: Calendar, oldCalendar: Calendar) -> Date {
20+
var newDate = self.dateOnly(calendar: oldCalendar)
21+
let diff = oldCalendar.timeZone.secondsFromGMT() - calendar.timeZone.secondsFromGMT()
22+
newDate.addTimeInterval(TimeInterval(diff))
23+
return newDate
24+
}
1725
}

Source/Header/DayHeaderView.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import DateToolsSwift
44

55
public final class DayHeaderView: UIView, DaySelectorDelegate, DayViewStateUpdating, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
66
public private(set) var daysInWeek = 7
7-
public var calendar: Calendar
7+
public var calendar: Calendar {
8+
didSet {
9+
daySymbolsView.calendar = calendar
10+
swipeLabelView.calendar = calendar
11+
configure() // TODO: Should I do it that way or better just to set a new vc without adding subview (like in state#didSet)?
12+
}
13+
}
814

915
private var style = DayHeaderStyle()
1016
private var currentSizeClass = UIUserInterfaceSizeClass.compact
@@ -16,6 +22,14 @@ public final class DayHeaderView: UIView, DaySelectorDelegate, DayViewStateUpdat
1622
didSet {
1723
state?.subscribe(client: self)
1824
swipeLabelView.state = state
25+
26+
// Fixes the "jump" of the pager from today to the selected date. This is noticeable
27+
// when we are on a date outside of today's week, and try to change the time zone.
28+
let previousSelectedDate = state!.selectedDate // day selected before timezone change
29+
let vc = makeSelectorController(startDate: beginningOfWeek(previousSelectedDate))
30+
vc.selectedDate = previousSelectedDate
31+
currentWeekdayIndex = vc.selectedIndex
32+
pagingViewController.setViewControllers([vc], direction: .forward, animated: false, completion: nil)
1933
}
2034
}
2135

Source/Header/DaySymbolsView.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ import UIKit
33

44
public final class DaySymbolsView: UIView {
55
public private(set) var daysInWeek = 7
6-
private var calendar = Calendar.autoupdatingCurrent
6+
public var calendar = Calendar.autoupdatingCurrent {
7+
didSet {
8+
// TODO: I honestly don't know if I should be doing this. Changes to
9+
// the timezone should not affect the displayed days of the week,
10+
// however, just in case, I am reconfiguring this view
11+
configure()
12+
setNeedsLayout()
13+
}
14+
}
715
private var labels = [UILabel]()
816
private var style: DaySymbolsStyle = DaySymbolsStyle()
917

Source/Header/SwipeLabelView.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ public final class SwipeLabelView: UIView, DayViewStateUpdating {
77
case Backward
88
}
99

10-
public private(set) var calendar = Calendar.autoupdatingCurrent
10+
public var calendar = Calendar.autoupdatingCurrent {
11+
didSet {
12+
// I doubt that someone will use this view without a state, but
13+
// I consider it necessary to update text label for such a situation
14+
updateLabelText()
15+
}
16+
}
1117
public weak var state: DayViewState? {
1218
willSet(newValue) {
1319
state?.unsubscribe(client: self)

Source/Timeline/TimelinePagerView.swift

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ public final class TimelinePagerView: UIView, UIGestureRecognizerDelegate, UIScr
2222

2323
public var calendar: Calendar = Calendar.autoupdatingCurrent {
2424
didSet {
25-
pagingViewController.viewControllers?.forEach {
25+
// changing timezone in loaded pages
26+
pagingViewController.children.forEach {
2627
let vc = $0 as! TimelineContainerController
28+
let oldCalendar = vc.timeline.calendar
29+
vc.timeline.date = vc.timeline.date.dateOnly(calendar: calendar, oldCalendar: oldCalendar)
2730
vc.timeline.calendar = calendar
2831
}
2932
}
@@ -180,7 +183,11 @@ public final class TimelinePagerView: UIView, UIGestureRecognizerDelegate, UIScr
180183

181184
private func updateTimeline(_ timeline: TimelineView) {
182185
guard let dataSource = dataSource else {return}
183-
let date = timeline.date.dateOnly(calendar: calendar)
186+
// I don't know under what circumstances, but I know for sure that
187+
// a situation is possible when these calendars have different time
188+
// zones. It is in this case that the call below will prevent a bug
189+
// that leads to "jumps" after days when you swipe to the left
190+
let date = timeline.date.dateOnly(calendar: calendar, oldCalendar: timeline.calendar)
184191
let events = dataSource.eventsForDate(date)
185192
let day = TimePeriod(beginning: date,
186193
chunk: TimeChunk.dateComponents(days: 1))
@@ -444,7 +451,7 @@ public final class TimelinePagerView: UIView, UIGestureRecognizerDelegate, UIScr
444451
// MARK: UIPageViewControllerDataSource
445452

446453
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
447-
guard let containerController = viewController as? TimelineContainerController else {return nil}
454+
guard let containerController = viewController as? TimelineContainerController else {return nil}
448455
let previousDate = containerController.timeline.date.add(TimeChunk.dateComponents(days: -1), calendar: calendar)
449456
let vc = configureTimelineController(date: previousDate)
450457
let offset = (pageViewController.viewControllers?.first as? TimelineContainerController)?.container.contentOffset
@@ -453,7 +460,7 @@ public final class TimelinePagerView: UIView, UIGestureRecognizerDelegate, UIScr
453460
}
454461

455462
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
456-
guard let containerController = viewController as? TimelineContainerController else {return nil}
463+
guard let containerController = viewController as? TimelineContainerController else {return nil}
457464
let nextDate = containerController.timeline.date.add(TimeChunk.dateComponents(days: 1), calendar: calendar)
458465
let vc = configureTimelineController(date: nextDate)
459466
let offset = (pageViewController.viewControllers?.first as? TimelineContainerController)?.container.contentOffset
@@ -466,7 +473,19 @@ public final class TimelinePagerView: UIView, UIGestureRecognizerDelegate, UIScr
466473
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
467474
guard completed else {return}
468475
if let timelineContainerController = pageViewController.viewControllers?.first as? TimelineContainerController {
469-
let selectedDate = timelineContainerController.timeline.date
476+
// Unfortunately, I cannot explain this change in detail. I fiddled
477+
// with a bug in which some days were skipped when swiping, completely
478+
// desperate and wrote this. To my surprise, this solved the problem.
479+
// I'll do some research on the reasons later.
480+
481+
// Попытка пофиксить сбой хедера с перескоком через число
482+
var selectedDate = timelineContainerController.timeline.date
483+
selectedDate = selectedDate.dateOnly(calendar: self.state!.calendar, oldCalendar: timelineContainerController.container.timeline.calendar)
484+
485+
// попытка пофиксить баг с уменьшением и свайпом
486+
timelineContainerController.timeline.date = selectedDate // Я хз как и какие последствия оно имеет, но это сработало
487+
timelineContainerController.timeline.calendar = self.state!.calendar
488+
470489
delegate?.timelinePager(timelinePager: self, willMoveTo: selectedDate)
471490
state?.client(client: self, didMoveTo: selectedDate)
472491
scrollToFirstEventIfNeeded()

0 commit comments

Comments
 (0)