iOS 11中如何实现点击TabBarItem触发类状态栏滚动到顶部动画
这个问题我做项目时也踩过坑!直接用scrollView.setContentOffset(.zero, animated: true)的动画曲线,确实和iOS 11+点击状态栏的原生效果不一样。App Store那种丝滑的动画其实是调用了系统内置的scrollToTop逻辑,下面给你两种安全靠谱的实现方式:
方法一:利用系统公开API触发原生动画
这种方式完全基于公开API,不用担心审核问题,步骤很简单:
确保ScrollView支持scrollToTop
首先要保证当前页面的UIScrollView(包括UITableView、UICollectionView)的scrollsToTop属性为true(默认就是true,除非你手动修改过)。监听TabBarItem的重复点击事件
在UITabBarController的代理方法里,判断用户是否点击了当前已选中的TabBarItem,只有重复点击时才触发滚动:func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { // 仅当点击当前已激活的item时执行滚动 guard let currentIndex = tabBarController.viewControllers?.firstIndex(of: viewController), currentIndex == tabBarController.selectedIndex else { return } // 触发系统原生scrollToTop动画 UIApplication.shared.sendAction(#selector(UIScrollView.scrollToTop), to: nil, from: nil, for: nil) }这段代码会让当前可见的、允许scrollToTop的ScrollView自动滚动到顶部,动画效果和点击状态栏完全一致!
方法二:针对特定ScrollView手动触发(适合多ScrollView场景)
如果页面存在多个ScrollView,或者需要指定某一个特定的ScrollView滚动,可以用这种方式:
获取目标ScrollView
从当前选中的ViewController中拿到对应的ScrollView(比如页面里的tableView或collectionView)。调用系统原生滚动方法
不要用setContentOffset,而是用scrollRectToVisible(_:animated:)指定顶部区域:// 假设目标ScrollView是tableView let topRect = CGRect(x: 0, y: 0, width: 1, height: 1) tableView.scrollRectToVisible(topRect, animated: true)这个方法的动画逻辑和系统scrollToTop完全一致,比直接设置contentOffset的动画更贴合原生体验。
注意事项
- 若使用自定义TabBar,记得在点击事件里判断是否为重复点击当前item,避免切换页面时误触发滚动。
- 确保ScrollView没有被其他视图完全遮挡,否则
scrollToTop可能无法生效。
内容的提问来源于stack exchange,提问作者zgjie

