iOSフォトアプリを模倣しようとしました。ここに私のロジックは次のとおりです。
// CALCULATE A CONTENT OFFSET FOR SNAPPING POINT
let snapPoint = CGPoint(x: 367, y: 0)
// CHANGE THESE VALUES TO TEST
let minDistanceToSnap = 7.0
let minVelocityToSnap = 25.0
let minDragDistanceToReleaseSnap = 7.0
let snapDuringDecelerating = false
スクロールのこの種は、3つの段階
enum SnapState {
case willSnap
case didSnap
case willRelease
}
willSnap:
デフォルトの状態を必要とします。スナップする時期を決めます。 contentOffset distance from SnapPoint with minDistanceToSnap
とscrollview velocity with minVelocityToSnap
を比較してください。 didSnap
状態に変更してください。
didSnap:
手動setContentOffset
と提供contextOffset(snapPoint)
。 scrollView
でdragDistance
を計算します。ユーザーが特定の距離(minDragDistanceToReleaseSnap
)以上ドラッグした場合、willRelease
状態になります。
willRelease:
distance scroll from snapPoint
がminDistanceToSnap
より大きい場合は、willSnap
州に再度変更してください。
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(scrollView: UIScrollView) {
switch(snapState) {
case .willSnap:
let distanceFromSnapPoint = distance(between: scrollView.contentOffset, and: snapPoint)
let velocity = scrollView.panGestureRecognizer.velocityInView(view)
let velocityDistance = distance(between: velocity, and: CGPointZero)
if distanceFromSnapPoint <= minDistanceToSnap && velocityDistance <= minVelocityToSnap && (snapDuringDecelerating || velocityDistance > 0.0) {
startSnapLocaion = scrollView.panGestureRecognizer.locationInView(scrollView)
snapState = .didSnap
}
case .didSnap:
scrollView.setContentOffset(snapPoint, animated: false)
var dragDistance = 0.0
let location = scrollView.panGestureRecognizer.locationInView(scrollView)
dragDistance = distance(between: location, and: startSnapLocaion)
if dragDistance > minDragDistanceToReleaseSnap {
startSnapLocaion = CGPointZero
snapState = .willRelease
}
case .willRelease:
let distanceFromSnapPoint = distance(between: scrollView.contentOffset, and: snapPoint)
if distanceFromSnapPoint > minDistanceToSnap {
snapState = .willSnap
}
}
}
}
ヘルパー機能のGithub上のデモプロジェクト製
func distance(between point1: CGPoint, and point2: CGPoint) -> Double {
return Double(hypotf(Float(point1.x - point2.x), Float(point1.y - point2.y)))
}
:https://github.com/rishi420/SnapDrag
注:Xcodeの7.2で作ったプロジェクト。コンパイルするにはビットを変更する必要があるかもしれません。
解決方法を見るhttps://stackoverflow.com/a/48493973/1275014 – thedeveloper3124