xyk blog

最近は iOS 開発の記事が多めです。

UIScrollViewDelegate について

環境: Xcode8.2.1, Swift3

UIScrollView のドラッグによるスクロール時に呼ばれる UIScrollViewDelegate の順番

// MARK: - UIScrollViewDelegate

// any offset changes
// スクロール中は常に呼ばれる
func scrollViewDidScroll(_ scrollView: UIScrollView) {

}

// 1. called on start of dragging (may require some time and or distance to move)
// ドラッグ開始時
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

}

// ここから下はドラッグ状態から指を離した後に呼ばれる

// 2. called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
// ドラッグの終わりの始まり
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

}

// 3. called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
// ドラッグの終わり
// decelerate が true ならまだ減速しながらスクロール中、false ならスクロールは止まっている。
// ドラッグをピタッと止めて、慣性なしでドラッグを終えた場合に decelerate = false になる。  
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {

}

// 4. called on finger up as we are moving
// 減速開始時 -> ★呼ばれない場合あり
// 3 で decelerate が true であれば呼ばれ、false であれば呼ばれない。
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {

}

// 5. called when scroll view grinds to a halt
// 減速終了時 -> ★呼ばれない場合あり
// 4 と同様に 3 で decelerate が true であれば呼ばれ、false であれば呼ばれない。
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

}

UIScrollView をプログラムでスクロールさせた場合に呼ばれる UIScrollDelegate の順番

例えば以下のようなコードでアニメーション付きでスクロールさせた場合

scrollView.setContentOffset(CGPoint(x: 320, y: 0), animated: true)

この場合は上記1~5のドラッグ系 Delegate は呼ばれずscrollViewDidScrollscrollViewDidEndScrollingAnimationのみ呼ばれる。

// MARK: - UIScrollViewDelegate

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

}

順番は以下のようになる。

scrollViewDidScroll
...
...
...
scrollViewDidScroll
scrollViewDidEndScrollingAnimation

ちなみに以下のようにアニメーションなしでスクロールさせた場合は

scrollView.setContentOffset(CGPoint(x: 320, y: 0), animated: false)

scrollViewDidEndScrollingAnimationは呼ばれずscrollViewDidScrollが1度だけ呼ばれる。

scrollViewDidScroll