Первым делом, я думаю, что ручное перемещение вида прокрутки - это то, чего я бы избегал. Вероятно, есть нечто гораздо более простое, чтобы выполнить необходимое вам поведение. Поэтому я настоятельно рекомендую вам и любому другому читателю не читать далее go далее при прочтении этого поста и вместо этого go вперед и попытаться решить проблему, которая в первую очередь направляла вас сюда.
Вы также можете задать еще один вопрос здесь о переполнении стека, чтобы, возможно, получить помощь, чтобы избежать ручного обновления позиции scrollView.
Так что, если вы все еще читаете, эту статью - это, вероятно, путь к go с реализацией чего-то, что действительно похоже на UIScrollView. Выполнение чего-либо еще, вероятно, действительно будет выглядеть и ощущаться ужасно.
По сути, оно состоит из использования UIKit Dynamics для управления инерцией.
Таким образом, вы можете создать объект, который соответствует UIDynamicItem (с ненулевым CGRect) и измените его центр вместо scrollView contentOffset, чем используйте UIDynamicAnimator и его UIDynamicBehavior, чтобы установить инерцию и соединить изменения во время анимации с соответствующим contentOffset в scrollView, используя UIDynamicBehavior's блок действия .
При условии, что у вас есть элемент, который является UIDynamicItem, и аниматором, который является UIDynamicAnimator, обработка распознавателя panGesture будет выглядеть примерно так:
func handlGestureRecognizer(panGesture: UIPanGestureRecognizer) {
switch panGesture.state {
case .began:
self.animator.removeAllBehaviors()
case .changed:
// Update scroll view position
break
case .ended:
var velocity = panGesture.velocity(in: panGesture.view!)
velocity.x = -velocity.x
velocity.y = -velocity.y
// You probably need to check for out of bound velocity too, and also put velocity.x to 0 if the scroll is only scrolling vertically
// This is done to just save the current content offset and then change it alongside the animation from this starting point
item.center = scrollView.contentOffset
let decelerationBehavior = UIDynamicItemBehavior(items: [item])
decelerationBehavior.addLinearVelocity(velocity, for: item)
decelerationBehavior.resistance = 2.0
decelerationBehavior.action = {
// Connect the item center to the scroll contentOffset. Probably something like this:
scrollView.contentOffset = item.center
}
self.animator.addBehavior(decelerationBehavior)
default:
break
}
}
Вам нужно просто поиграть со значениями поведения и быть осторожным со скоростью, которую вы вкладываете в поведение, с особой тщательностью при взгляде на крайние случаи (если вы, например, прокручиваете мин / макс)
PS: В конце концов я написано, я все еще верю, что вам настоятельно следует не делать этого и вместо этого go со стандартной прокруткой scrollView, избегая ручных обновлений.