gpt4 book ai didi

ios - UIAnimator 的 UISnapBehavior 可以与 UIScrollview 一起使用吗?

转载 作者:可可西里 更新时间:2023-11-01 00:36:25 32 4
gpt4 key购买 nike

我想弄清楚是否可以在 UIScrollview 中使用 UIAnimator 中的 UISnapBehavior 来使 ScrollView 的内容对齐到一个点。到目前为止,我的发现导致这是不可能的。

我正在努力实现的目标

UIScrollView 在用户拖动 ScrollView 时“捕捉”到特定点。但是,滚动必须从捕捉位置恢复,而无需用户解除触摸。

Apple 似乎在其 iOS 照片应用程序的照片编辑中实现了这一点。 (见下面的截图)

enter image description here

我尝试了什么

我试图通过将 UIPanGestureRecognizer 附加到 ScrollView 并使用它的速度来获得此行为。如果用户向捕捉点拖动, ScrollView 将禁用滚动,动画到捕捉点,完成动画后它将重新启用滚动。

但是,这会导致用户必须在拖动并重新拖动 ScrollView 后取消触摸。然而,Apple 似乎在没有解除阻力的情况下就做到了。

最佳答案

我尝试模仿 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
}
  1. willSnap:默认状态。决定何时捕捉。比较 contentOffset distance from SnapPoint with minDistanceToSnapscrollview velocity with minVelocityToSnap .改为didSnap状态。
  2. didSnap:手动 setContentOffset到提供的 contextOffset(snapPoint) .计算 dragDistancescrollView .如果用户拖动超过一定距离 ( minDragDistanceToReleaseSnap ) 更改为 willRelease状态。
  3. willRelease:改为willSnap如果 distance scroll from snapPoint 再次声明大于minDistanceToSnap .


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
}
}
}
}

辅助函数

func distance(between point1: CGPoint, and point2: CGPoint) -> Double {
return Double(hypotf(Float(point1.x - point2.x), Float(point1.y - point2.y)))
}

在Github上做了一个演示项目:https://github.com/rishi420/SnapDrag

注意:使用 Xcode 7.2 制作的项目。您可能需要稍作更改才能编译。

关于ios - UIAnimator 的 UISnapBehavior 可以与 UIScrollview 一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38465498/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com