TableViewのSectionIndexTitlesの位置を調整する
はじめに
TableView でデータをリスト表示している際に、セクションをいい感じに表示してくれる SectionIndexTitles
というものがあります。
連絡先アプリ | ミュージック |
---|---|
この SectionIndexTitles
は TableView のデリゲートメソッドである sectionIndexTitles(for:)
を実装するだけで表示することができます。
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
// セクションごとに分けたデータのタイトル等
return ["あ", "か", "さ" ...]
}
やりたかったこと
そんな SectionIndexTitles
ですが、UISearchController
などと一緒に使っていて、かつデータの量が多くなるとキーボードで隠れてしまうことがあります。
短いとき | 長いとき |
---|---|
一応ドラッグすることで、キーボードで隠れてしまっている部分も操作することができますが、連絡先アプリ等を触ってみると、キーボード表示時には SectionIndexTitles
が上にスライドしていることが分かります。
連絡先アプリ |
---|
今回はこの挙動を目指して実装してみます。
また、以下のリポジトリにサンプルを作成したので、全体のコードが見たい方はそちらを参照してください🙇♂️
方針
キーボード表示のタイミングで TableView にキーボードの高さ分 contentInset
を設けてあげることで、それっぽい動きを再現することができました。
final class ViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// ...
configureObserver()
}
private func configureObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShowNotification(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHideNotification), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc private func handleKeyboardWillShowNotification(_ notification: Notification?) {
guard let rect = (notification?.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return
}
UIView.performWithoutAnimation {
self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: rect.height, right: 0)
self.tableView.layoutIfNeeded()
}
}
@objc private func handleKeyboardWillHideNotification() {
UIView.performWithoutAnimation {
self.tableView.contentInset = .zero
self.tableView.layoutIfNeeded()
}
}
}
アニメーションをオフにしているのは、アニメーションありだと SectionIndexTitles
が伸縮して若干気持ち悪かったのでオフにしています。
この実装で連絡先アプリと似たような挙動を再現することができました。
アニメーションなし | アニメーションあり |
---|---|
他にも SectionIndexTitles
は UITableView
から生えている以下のプロパティで見た目等を調節することができます。
-
sectionIndexColor
: 文字色 -
sectionIndexBackgroundColor
: 通常時の背景色 -
sectionIndexTrackingBackgroundColor
: トラッキング時の背景色 -
sectionIndexMinimumDisplayRowCount
: いくつの要素があったときにsectionIndexTitles
に項目を表示するか?( 指定しても特に変化がありませんでした🤔 )
さいごに
SectionIndexTitles
に関しての情報は調べてもあまり出てこなかったので残しておきます。
この情報が誰かの助けになれば幸いです。
- 20210312 追記
UITableViewController
を使ってもう少し調べてみました。
Discussion