よくInstagramやFacebookで実装されている、TabBarItemを押すとページの最上部までスクロールできる機能。
意外と実装方法に関する情報が少なく、特に日本語での記事が皆無に近かったので記録として残します。
実装
今回はCollection Viewを使用した時に参考になる例を扱います。同じくTable Viewでも少しいじるだけで実装できるはずです。
ViewController.swift
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITabBarControllerDelegate {
@IBOutlet weak var collectionView: UICollectionView!
var canScrollToTop: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.delegate = self
canScrollToTop = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
canScrollToTop = false
}
// TabBarItemが押下された時に呼ばれる
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
// 呼ばれたTabBarItemの番号(0, 1,..)
let tabBarIndex = tabBarController.selectedIndex
// 一応確認する
print(tabBarIndex)
if tabBarIndex == 0 && canScrollToTop {
// 一番上に移動
self.collectionView.setContentOffset(CGPoint.zero, animated: true)
}
}
}
ポイント
canScrollToTop
の設置
一度目のdidSelectで受け取った押下アクションはTabを切り替える時に発動されるので、二度目のアクションでViewのトップへスクロールしたい。
そんな時に、canScrollToTop
をfunc viewWillAppear
でtrue
、func viewWillDisappear
でfalse
にすることで任意のTabBar上にいるときのみdidSelect
を呼べます。
複数のタブ上でViewを動かしたいときのself.tabBarController?.delegate = self
の位置
self.tabBarController?.delegate = self
これをviewDidLoad()
でなく、各ViewControllerのviewWillAppear
の中で呼ぶことによって、VCごとの要素を使ったアクションを実装することが可能です。
終わりに
UITabBarController
やUITabBarControllerDelegate
を使用してTabBarが押された時のアクションを追加する方法もいくつか見かけましたが、ViewControllerごとのCollection Viewだったりを使用したかったので今回の実装方法が一番しっくりきました。
他に良い方法があれば是非教えてください!