WalterBeiter
WalterBeiter

Reputation: 2364

scroll to top of tableview and show large title iOS

I want to scroll to the top of my tableView and also show the largeTitle in the navigationBar when I tap on the tab in the tabbar.

Using the scrollToRow method does not show the largeTitle:

extension TableViewConstroller: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if tabBarController.selectedIndex == 1 {
            let indexPath = IndexPath(row: 0, section: 0)
            tableView.scrollToRow(at: indexPath, at: .top, animated: true)
        }
    }
}

I also tried

self.tableView.scrollRectToVisible(CGRect(x: 0, y: -64, width: 1, height: 1), animated: true)

This works sometimes, but if I scroll way down the tableView, the navigationBar is still collapsed when this method scrolls up.

What can I do to mimic the behavior of the tableView's scrollsToTop property that does scroll to the top and shows the largeTitle? It animates very smoothly and always shows the large navigationBar.

Upvotes: 3

Views: 1194

Answers (1)

WalterBeiter
WalterBeiter

Reputation: 2364

I used these two methods inside the UITabBarControllerDelegate: The second method searches for the first scrollView and then scrolls to the top on that scrollView. And since a tableView is also a scrollView, this approach works.

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if tabBarController.selectedViewController == viewController {
        if let scrollView = findScrollView(in: viewController.view) {
            let desiredOffset = CGPoint(x: 0, y: -scrollView.contentInset.top - 96 + UIApplication.shared.statusBarFrame.height)
            scrollView.setContentOffset(desiredOffset, animated: true)
        }
    }
    return true
}

private func findScrollView(in view: UIView) -> UIScrollView? {
    if let scrollView = view as? UIScrollView {
        return scrollView
    } else {
        for subview in view.subviews {
            if let scrollView = findScrollView(in: subview) {
                return scrollView
            }
        }
    }
    return nil
}

Upvotes: 1

Related Questions