UIScrollView привязка к позиции при прокрутке
Я пытаюсь реализовать вид прокрутки, который привязывается к точкам при прокрутке.
все сообщения здесь, которые я видел о привязке к точке "после", пользователь закончил перетаскивание прокрутки. Я хочу, чтобы он щелкнул во время перетаскивания.
до сих пор у меня есть это, чтобы остановить инерцию после перетаскивания, и она отлично работает:
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
targetContentOffset.memory = scrollView.contentOffset
}
Я пробовал это, но не работает как хотелось:
var scrollSnapHeight : CGFloat = myScrollView.contentSize.height/10
scrollViewDidScroll:
func scrollViewDidScroll(scrollView: UIScrollView) {
let remainder : CGFloat = scrollView.contentOffset.y % scrollSnapHeight
var scrollPoint : CGPoint = scrollView.contentOffset
if remainder != 0 && scrollView.dragging
{
if self.lastOffset > scrollView.contentOffset.y //Scrolling Down
{
scrollPoint.y += (scrollSnapHeight - remainder)
NSLog("scrollDown")
}
else //Scrolling Up
{
scrollPoint.y -= (scrollSnapHeight - remainder)
}
scrollView .setContentOffset(scrollPoint, animated: true)
}
self.lastOffset = scrollView.contentOffset.y;
}
2 ответов
этот подход позволяет включить / отключить scrollEnabled
собственность UIScrollView
.
когда scrollView прокручивается за пределами данного scrollSnapHeight
, выберите scrollEnabled
to false
. Это остановит прокрутку. Затем снова включите прокрутку для следующего перетаскивания.
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y > lastOffset + scrollSnapHeight {
scrollView.scrollEnabled = false
} else if scrollView.contentOffset.y < lastOffset - scrollSnapHeight {
scrollView.scrollEnabled = false
}
}
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
guard !decelerate else {
return
}
setContentOffset(scrollView)
}
func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
setContentOffset(scrollView)
}
}
func setContentOffset(scrollView: UIScrollView) {
let stopOver = scrollSnapHeight
var y = round(scrollView.contentOffset.y / stopOver) * stopOver
y = max(0, min(y, scrollView.contentSize.height - scrollView.frame.height))
lastOffset = y
scrollView.setContentOffset(CGPointMake(scrollView.contentOffset.x, y), animated: true)
scrollView.scrollEnabled = true
}
Подкласс UIScrollView / UICollectionView
Это решение не требует, чтобы вы подняли палец, чтобы разомкнуть и работает во время прокрутки. Если вам это нужно для вертикальной прокрутки, а не горизонтальной прокрутки, просто замените x на y.
Set snapPoint к смещению содержимого, где вы хотите, чтобы центр привязки был.
Set snapOffset к радиусу вокруг точки, где вы хотите привязать к происходить.
Если вам нужно знать, если scrollView щелкнул, просто проверьте isSnapped переменной.
class UIScrollViewSnapping : UIScrollView {
public var snapPoint: CGPoint?
public var snapOffset: CGFloat?
public var isSnapped = false
public override var contentOffset: CGPoint {
set {
if let snapPoint = self.snapPoint,
let snapOffset = self.snapOffset,
newValue.x > snapPoint.x - snapOffset,
newValue.x < snapPoint.x + snapOffset {
self.isSnapped = true
super.contentOffset = snapPoint
}
else {
self.isSnapped = false
super.contentOffset = newValue
}
}
get {
return super.contentOffset
}
}
}