From 3d7ade174781294b20fa0640cbf54e11cb9e1490 Mon Sep 17 00:00:00 2001 From: CMK Date: Mon, 14 Feb 2022 14:55:00 +0800 Subject: [PATCH] feat: restore scroll-to-top tap gesture for TabBar --- Mastodon/Protocol/ScrollViewContainer.swift | 4 +- .../HomeTimelineViewController.swift | 6 ++- .../NotificationTimelineViewController.swift | 7 +++ .../NotificationViewController.swift | 10 +++++ .../About/ProfileAboutViewController.swift | 2 +- .../Scene/Profile/ProfileViewController.swift | 44 +++++++++---------- .../Timeline/UserTimelineViewController.swift | 2 +- 7 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Mastodon/Protocol/ScrollViewContainer.swift b/Mastodon/Protocol/ScrollViewContainer.swift index ae79d0e0..c9f10ba3 100644 --- a/Mastodon/Protocol/ScrollViewContainer.swift +++ b/Mastodon/Protocol/ScrollViewContainer.swift @@ -8,12 +8,12 @@ import UIKit protocol ScrollViewContainer: UIViewController { - var scrollView: UIScrollView { get } + var scrollView: UIScrollView? { get } func scrollToTop(animated: Bool) } extension ScrollViewContainer { func scrollToTop(animated: Bool) { - scrollView.scrollRectToVisible(CGRect(origin: .zero, size: CGSize(width: 1, height: 1)), animated: animated) + scrollView?.scrollRectToVisible(CGRect(origin: .zero, size: CGSize(width: 1, height: 1)), animated: animated) } } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 2af35707..0fda3a48 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -579,9 +579,13 @@ extension HomeTimelineViewController: TimelineMiddleLoaderTableViewCellDelegate // MARK: - ScrollViewContainer extension HomeTimelineViewController: ScrollViewContainer { - var scrollView: UIScrollView { return tableView } + var scrollView: UIScrollView? { return tableView } func scrollToTop(animated: Bool) { + guard let scrollView = scrollView else { + return + } + if scrollView.contentOffset.y < scrollView.frame.height, viewModel.loadLatestStateMachine.canEnterState(HomeTimelineViewModel.LoadLatestState.Loading.self), (scrollView.contentOffset.y + scrollView.adjustedContentInset.top) == 0.0, diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift index 301b2f37..24663082 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewController.swift @@ -176,3 +176,10 @@ extension NotificationTimelineViewController: UITableViewDelegate, AutoGenerateT // MARK: - NotificationTableViewCellDelegate extension NotificationTimelineViewController: NotificationTableViewCellDelegate { } + +// MARK: - ScrollViewContainer +extension NotificationTimelineViewController: ScrollViewContainer { + + var scrollView: UIScrollView? { tableView } + +} diff --git a/Mastodon/Scene/Notification/NotificationViewController.swift b/Mastodon/Scene/Notification/NotificationViewController.swift index aa49680a..e1f418e2 100644 --- a/Mastodon/Scene/Notification/NotificationViewController.swift +++ b/Mastodon/Scene/Notification/NotificationViewController.swift @@ -593,3 +593,13 @@ extension NotificationViewController: UITableViewDelegate { // } // //} + +// MARK: - ScrollViewContainer +extension NotificationViewController: ScrollViewContainer { + var scrollView: UIScrollView? { + guard let viewController = currentViewController as? NotificationTimelineViewController else { + return nil + } + return viewController.scrollView + } +} diff --git a/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift b/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift index 9b386847..4879be74 100644 --- a/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift +++ b/Mastodon/Scene/Profile/About/ProfileAboutViewController.swift @@ -162,7 +162,7 @@ extension ProfileAboutViewController: ProfileFieldEditCollectionViewCellDelegate // MARK: - ScrollViewContainer extension ProfileAboutViewController: ScrollViewContainer { - var scrollView: UIScrollView { + var scrollView: UIScrollView? { collectionView } } diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 8fe8ad2b..75b4eeb3 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -375,9 +375,12 @@ extension ProfileViewController { viewModel.viewDidAppear.send() // set overlay scroll view initial content size - guard let currentViewController = profileSegmentedViewController.pagingViewController.currentViewController as? ScrollViewContainer else { return } - currentPostTimelineTableViewContentSizeObservation = observeTableViewContentSize(scrollView: currentViewController.scrollView) - currentViewController.scrollView.panGestureRecognizer.require(toFail: overlayScrollView.panGestureRecognizer) + guard let currentViewController = profileSegmentedViewController.pagingViewController.currentViewController as? ScrollViewContainer, + let scrollView = currentViewController.scrollView + else { return } + + currentPostTimelineTableViewContentSizeObservation = observeTableViewContentSize(scrollView: scrollView) + scrollView.panGestureRecognizer.require(toFail: overlayScrollView.panGestureRecognizer) } override func viewDidDisappear(_ animated: Bool) { @@ -787,7 +790,7 @@ extension ProfileViewController: UIScrollViewDelegate { if scrollView.contentOffset.y < topMaxContentOffsetY { self.containerScrollView.contentOffset.y = scrollView.contentOffset.y for postTimelineView in profileSegmentedViewController.pagingViewController.viewModel.viewControllers { - postTimelineView.scrollView.contentOffset.y = 0 + postTimelineView.scrollView?.contentOffset.y = 0 } contentOffsets.removeAll() } else { @@ -797,7 +800,7 @@ extension ProfileViewController: UIScrollViewDelegate { } else { if let customScrollViewContainerController = profileSegmentedViewController.pagingViewController.currentViewController as? ScrollViewContainer { let contentOffsetY = scrollView.contentOffset.y - containerScrollView.contentOffset.y - customScrollViewContainerController.scrollView.contentOffset.y = contentOffsetY + customScrollViewContainerController.scrollView?.contentOffset.y = contentOffsetY } } @@ -840,8 +843,10 @@ extension ProfileViewController: ProfilePagingViewControllerDelegate { overlayScrollView.contentOffset.y = contentOffsets[index] ?? containerScrollView.contentOffset.y // setup observer and gesture fallback - currentPostTimelineTableViewContentSizeObservation = observeTableViewContentSize(scrollView: postTimelineViewController.scrollView) - postTimelineViewController.scrollView.panGestureRecognizer.require(toFail: overlayScrollView.panGestureRecognizer) + if let scrollView = postTimelineViewController.scrollView { + currentPostTimelineTableViewContentSizeObservation = observeTableViewContentSize(scrollView: scrollView) + scrollView.panGestureRecognizer.require(toFail: overlayScrollView.panGestureRecognizer) + } } } @@ -1098,29 +1103,20 @@ extension ProfileViewController: MastodonMenuDelegate { } // MARK: - ScrollViewContainer -//extension ProfileViewController: ScrollViewContainer { -// var scrollView: UIScrollView { return overlayScrollView } -//} -// +extension ProfileViewController: ScrollViewContainer { + var scrollView: UIScrollView? { + return overlayScrollView + } +} + //extension ProfileViewController { -// +// // override var keyCommands: [UIKeyCommand]? { // if !viewModel.isEditing.value { // return segmentedControlNavigateKeyCommands // } -// +// // return nil // } -// -//} - -// MARK: - SegmentedControlNavigateable -//extension ProfileViewController: SegmentedControlNavigateable { -// var navigateableSegmentedControl: UISegmentedControl { -// profileHeaderViewController.pageSegmentedControl -// } // -// @objc func segmentedControlNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { -// segmentedControlNavigateKeyCommandHandler(sender) -// } //} diff --git a/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift b/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift index 0b836da7..1fb37f30 100644 --- a/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift +++ b/Mastodon/Scene/Profile/Timeline/UserTimelineViewController.swift @@ -125,7 +125,7 @@ extension UserTimelineViewController: UITableViewDelegate, AutoGenerateTableView // MARK: - CustomScrollViewContainerController extension UserTimelineViewController: ScrollViewContainer { - var scrollView: UIScrollView { return tableView } + var scrollView: UIScrollView? { return tableView } } // MARK: - StatusTableViewCellDelegate