How to tap again on tab bar item to scroll top in iOS

Issue #990

In many popular apps like LinkedIn, Reddit, we can tap again on a bar bar item to scroll to top. Although this behavior is not built in by iOS, we can implement that very easily.

The idea is to keep track of previous selection so we can compare if user has indeed tapped on the tab bar item again.

final class TabBarController: UITabBarController {
    override var selectedViewController: UIViewController? {
        didSet {
            if previousSelectedViewController == selectedViewController {
                onTapAgain?()
            }

            previousSelectedViewController = selectedViewController
        }
    }

    var onTapAgain: (() -> Void)?
    private weak var previousSelectedViewController: UIViewController? 

}

Here we use selectedviewcontroller, which is changed when user manually changes the selected index path. It is same as we observe UITabBarControllerDelegate ’s tabBarController(_:didSelect:)

The selectedindex, however, is called when we change selectedIndex property, not when user changes selectedviewcontroller

Then we can handle to call scrollToItem

private func handleOnTapAgain() {
    guard
        let navigationController = tabBarController?.selectedViewController as? UINavigationController,
        let viewController = navigationController.topViewController as? UICollectionViewController,
        viewController.collectionView.numberOfSections > 0,
        viewController.collectionView.numberOfItems(inSection: 0) > 0
    else { return }

    viewController.collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .top, animated: true)
}

Or we can simply set content offset

viewController.collectionView.setContentOffset(.zero, animated: true)
Written by

I’m open source contributor, writer, speaker and product maker.

Start the conversation