[iOS] UITableViewでパララックス効果を試して見た

2016.12.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

奥行きや遠近感のことをパララックス(Parallax)「視差効果」と言います。

アプリやWebページで、スクロールなどの動作に応じて、レイヤ毎に異なるスピードで動かすことで立体感や奥行きを演出する手法を、パララックス効果と呼びます。

今回は、iPhoneのテーブルビューで、この手法を実装してみました。

作業の手順は、次の4つです。

  • 画像を表示する枠ビューを用意する
  • 枠ビューより大きなサイズの画像ビューを用意する
  • スクロール時に、セルのオフセットを取得する
  • セルのオフセットに応じて枠ビュー上の画像ビューのオフセットを変化させる

そして、下記が、動作しているようするです。

2 実装

(1) 画像を表示する枠ビューを用意する

最初にUITableCellの、Row Heightを固定値で指定しました。 そして、その中に、上下左右に10ptの制約を指定したビューを置きます。 これが、枠ビューとなります。(ここからイメージビュー(画像)を覗き込む感じです。) 006

(2) 枠ビューより大きなサイズの画像ビューを用意する

上で作成した枠ビューの中に、UIImageViewを置き、左右を 0pt そして、上下に -50pt を制約を指定します。 007

結果的に、UIImageViewは、枠ビューから上下にはみ出した状態になります。 008

続いて、枠ビューのClio To Boundsにチェックを入れて、枠ビューからはみ出た部分は、見えなくなるようにします。

009

ここまでの作業で、UIImageViewのオフセットを0-100に変化させることで、枠から覗き込める画像が上下にスライドするのが確認できます。

012 010 013

(3) スクロール時に、セルのオフセットを取得する

UITableViewのスクロールは、scrollViewDidScroll(_:)で取得が可能です。

インデックスから当該セルのFrameを取得し(①)、これを親となるUITableViewの相対位置に変換し(②)、セルの中心が、親テーブルのどの位置(0〜1.0で表現)になるかを算出しています。(③)

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    for index in tableView.indexPathsForVisibleRows! {
        let cell = tableView.cellForRow(at: index) as! TableViewCell   
        let rect = tableView.rectForRow(at:index) // ①
        let rectInTable = tableView.convert(rect, to: tableView.superview) // ②
        let offset = rectInTable.origin.y + rectInTable.height / 2 // ③
        let percentage = offset / tableView.bounds.height

上記のコードで、やりたいことを図示すると次のようなイメージになります。

001

各セルは、スクロールすると、テーブルビュー上で上下を移動するわけですが、移動のたびに、このオフセットを取得し、テーブルビュー全体のサイズで割ることで、どの位置に存在しているかを表しています。

そして、この数値は、この後、画像をずらすために使用します。

002 004 003

(4) セルのオフセットに応じて枠ビュー上の画像ビューのオフセットを変化させる

画像ビューをづらす作業は、frameorigin.yを変化させるだけです。

全部で0-100まで、ずらすので、先程取得した01.0-100 倍して、そのまま使用しています。

let percentage = offset / tableView.bounds.height

// ImageViewのframeを遷移させる
var imageRect = cell.photoView.frame
imageRect.origin.y = percentage * 100 * -1
cell.photoView.frame = imageRect

3 最後に

変化量は、極めて適当に実装してしまいましたが、簡単な実装で、非常に表現力を上げる手法だと思いました。

コードは下記に置きました。気になるところが有りましたら、ぜひ教えてやってください。
github [GitHub] https://github.com/furuya02/ParallaxSample

4 参考資料


Gorgeous parallax scrolling with UITableViewCells