【iOS】特定のセルがUITableViewの表示領域内に収まっているかどうかを調べる
記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。
特定のセルがUITableViewの表示領域内に収まっているかどうかを調べる方法を紹介します。
(もしもっと良い方法があればTwitterなどでぜひ教えて下さい! ⇒ @akio0911 | Twitter)
「収まっている」とは?
まず、どのような状況だと「特定のセルがUITableViewの領域内に収まっている」と言えるのかを考えてみましょう。
上の図で白線がUITableView、緑の四角が特定のセルだとします。
ここでは下端の条件だけ示しますが、セルの下端が白線より上にあれば「収まっている」と言えますし、セルの下端が白線より下にあれば「収まっていない」と言えるでしょう。上端の条件についても同様です。
特定のセルのframeを調べる
まずは判断材料として必要な「特定のセルのframe」を取得しましょう。UITableViewのメソッドである「rectForRowAtIndexPath(_:)」が使えます。以下、11行目のセルのframeを調べるコード例です。
let indexPath = NSIndexPath(forRow: 10, inSection: 0) let cellRect = tableView.rectForRowAtIndexPath(indexPath)
以下に実行結果を示します。
背景色がグレーのセルが、frame取得対象のセルです。
frame取得対象のセルが上の方に表示されているケース(左側)と下の方に表示されているケース(右側)で、取得したframe(cellRect)が同じ値となってしまっていますが、これは取得したframeがUITableView内での座標系だからです。
convertRectで別の座標系でのframeに変換する
というわけで、rectForRowAtIndexPath(_:)で取得したframeを、別の座標系でのframeに変換しましょう。
今回の例ではUINavigationControllerの中にUITableViewControllerを収めているので、navigationController?.viewの座標系に変換してみます。以下、コードです。
let indexPath = NSIndexPath(forRow: 10, inSection: 0) let cellRect = tableView.rectForRowAtIndexPath(indexPath) let cellRectInView = tableView.convertRect(cellRect, toView: navigationController?.view)
実行結果は以下の通りとなります。
先ほどと違って、スクロール位置によってセルのframeの値が異なっています。
収まっているかどうかをチェックする
チェックに必要な値は取得できたので、あとは判定を行うだけです。以下、コードです。
let indexPath = NSIndexPath(forRow: 10, inSection: 0)
let cellRect = tableView.rectForRowAtIndexPath(indexPath)
let cellRectInView = tableView.convertRect(cellRect, toView: navigationController?.view)
if tableView.frame.minY + tableView.scrollIndicatorInsets.top <= cellRectInView.minY && cellRectInView.maxY <= tableView.frame.maxY { print("収まっている") } else { print("収まっていない") } [/swift]
tableView.scrollIndicatorInsets.topを足しているのは、UITableViewがナビゲーションバーの下に潜り込んでいるのでそれを考慮するためです。
@akio0911はこう思った。
「特定のセルがはみ出ていたら画面内に収まるようスクロールする」「特定のセルが画面内に収まっていたら何かを行う」などを実現するのに使ってみてください。
関連記事
この記事が気に入ったら「いいね!」しよう
Twitterで更新情報をゲット!