Skip to content

Commit 89f026b

Browse files
committed
Scroll to the current session instead of just scrolling to the top
1 parent 69c8d22 commit 89f026b

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

trySwift/RootTabBar/RootTabBarController.swift

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,33 @@ class RootTabBarController: UITabBarController, UITabBarControllerDelegate {
1515
}
1616

1717
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
18-
if let splitViewController = viewController as? UISplitViewController {
19-
if let navigationController = splitViewController.viewControllers.last as? UINavigationController {
20-
if navigationController.viewControllers.count > 1 {
21-
navigationController.popViewController(animated: true)
18+
guard
19+
let splitViewController = viewController as? UISplitViewController,
20+
let navigationController = splitViewController.viewControllers.last as? UINavigationController
21+
else {
22+
return
23+
}
24+
25+
// if several view controllers are in the stack, pop to the root
26+
if navigationController.viewControllers.count > 1 {
27+
navigationController.popToRootViewController(animated: true)
28+
} else {
29+
// if there's at least one view controller in the stack (which there always should be)
30+
if let firstController = navigationController.viewControllers.first {
31+
// we either delegate to the controller since it knows better how to scroll to the top
32+
if let scrollableToTop = firstController as? ScrollableToTop {
33+
scrollableToTop.scrollAfterTabTap()
34+
// or we find the topmost scroll view and scroll it to the top
2235
} else {
23-
navigationController.viewControllers.first?.scrollToTop()
36+
firstController.view.findScrollSubview()?.setContentOffset(.zero, animated: true)
2437
}
2538
}
2639
}
2740
}
2841
}
2942

30-
private extension UIViewController {
31-
func scrollToTop() {
32-
let scrollView = view.findScrollSubview()
33-
scrollView?.setContentOffset(.zero, animated: true)
34-
}
43+
protocol ScrollableToTop {
44+
func scrollAfterTabTap()
3545
}
3646

3747
private extension UIView {

trySwift/ScheduleViewController.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class ScheduleViewController: ButtonBarPagerTabStripViewController {
3535

3636
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
3737
return days.map { SessionsTableViewController(conferenceDay: $0, scheduleViewController: self) }
38-
3938
}
4039

4140
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
@@ -47,6 +46,13 @@ class ScheduleViewController: ButtonBarPagerTabStripViewController {
4746
}
4847
}
4948

49+
extension ScheduleViewController: ScrollableToTop {
50+
func scrollAfterTabTap() {
51+
let controller = viewControllers[currentIndex] as! SessionsTableViewController
52+
controller.scrollAfterTabTap()
53+
}
54+
}
55+
5056
private extension ScheduleViewController {
5157

5258
func moveToCorrectDate() {

trySwift/SessionsTableViewController.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import UIKit
1010
import XLPagerTabStrip
1111
import TrySwiftData
1212

13+
1314
class SessionsTableViewController: UITableViewController {
1415

1516
var conferenceDay: ConferenceDay
@@ -216,3 +217,36 @@ private extension SessionsTableViewController {
216217
return workshopDetailVC
217218
}
218219
}
220+
221+
extension SessionsTableViewController: ScrollableToTop {
222+
func scrollAfterTabTap() {
223+
if tableView.contentOffset.y > 1 {
224+
tableView.setContentOffset(.zero, animated: true)
225+
} else {
226+
scrollToCurrentTime()
227+
}
228+
}
229+
230+
private func scrollToCurrentTime() {
231+
// find current block
232+
tableView.scrollToRow(at: IndexPath(row: 0, section: currentBlockIndex()),
233+
at: UITableViewScrollPosition.middle,
234+
animated: true)
235+
}
236+
237+
private func currentBlockIndex() -> Int {
238+
let time = Date()
239+
// if current time is within any given session, return its index,
240+
// if the time is earlier than the first session, return first session
241+
// otherwise return last session
242+
if let offset = conferenceDay.sessionBlocks.enumerated().first(where: {
243+
$0.element.startTime <= time && $0.element.endTime >= time
244+
})?.offset {
245+
return offset
246+
} else if let block = conferenceDay.sessionBlocks.first, block.startTime > time {
247+
return 0
248+
} else {
249+
return conferenceDay.sessionBlocks.count - 1
250+
}
251+
}
252+
}

0 commit comments

Comments
 (0)