your3i’s blog

iOSエンジニア。頑張る⚉

複数のscroll viewを同時にスクロール

なにそれ

おしゃれなウォークスルーでよくParallax Scrollingぽいデザインを見かける。それを実現するために、複数のscroll viewを使う必要がある。本当に動くの?興味があってやってみた。

画像がないと分からないよ

こんな簡単なものを作ってみた。

f:id:your3i:20181209141931g:plain

作り方

レイアウト

f:id:your3i:20181209142417p:plain

コード

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var outerScrollView: UIScrollView!
    @IBOutlet weak var bottomScrollView: UIScrollView!
    @IBOutlet weak var topScrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // To scroll the top scroll view backward,
        // first set the top scroll view scrolled to the right edge
        topScrollView.contentOffset = CGPoint(x: topScrollView.bounds.width, y: 0.0)
    }
}

extension ViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard scrollView == outerScrollView else {
            return
        }

        // Calculate scroll progress
        let outerScrollDistance = outerScrollView.contentSize.width - outerScrollView.bounds.width
        let progress = scrollView.contentOffset.x / outerScrollDistance

        // Scroll the top scroll view backward programmatically
        let topScrollDistance = topScrollView.contentSize.width - topScrollView.bounds.width
        let topOffsetX = (1 - progress) * topScrollDistance
        topScrollView.contentOffset = CGPoint(x: topOffsetX, y: 0.0)

        // Scroll the bottom scroll view forward programmatically
        let bottomScrollDistance = bottomScrollView.contentSize.width - bottomScrollView.bounds.width
        let bottomOffsetX = progress * bottomScrollDistance
        bottomScrollView.contentOffset = CGPoint(x: bottomOffsetX, y: 0.0)
    }
}

もうちょっと補足

  • outer scroll view が trigger として、ほかのscroll view を動かしたいので、outer scroll view だけ、delegateをこのview controllerに設定する
  • 全画面のどこでスワイプしてもouter scroll viewを動かすために、top scroll view と bottom scroll viewのscroll enabled と user interaction enabledをOFFにしている

おわりに

意外と簡単にできる。
かっこいいParallax Scrollingをできるために多分まだ色々計算が必要だね。

Source code