滚动时 UIScrollView 对齐位置
UIScrollView snap-to-position while scrolling
我正在尝试实现一个滚动视图,它在滚动时捕捉到点。
我在这里看到的所有关于捕捉到一个点的帖子 'after' 用户已结束拖动滚动条。我想让它在拖动过程中捕捉。
到目前为止,我用这个来停止拖动后的惯性,它工作正常:
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;
}
此方法将启用/禁用 UIScrollView
的 scrollEnabled
属性。
当 scrollView 滚动到给定 scrollSnapHeight
之外时,使 scrollEnabled
变为 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 交换即可。
将 snapPoint 设置为您希望快照中心所在的内容偏移量。
将 snapOffset 设置为您想要的 snapPoint 周围的半径,以便捕捉应该发生的位置。
如果您需要知道 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
}
}
}
我正在尝试实现一个滚动视图,它在滚动时捕捉到点。
我在这里看到的所有关于捕捉到一个点的帖子 'after' 用户已结束拖动滚动条。我想让它在拖动过程中捕捉。
到目前为止,我用这个来停止拖动后的惯性,它工作正常:
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;
}
此方法将启用/禁用 UIScrollView
的 scrollEnabled
属性。
当 scrollView 滚动到给定 scrollSnapHeight
之外时,使 scrollEnabled
变为 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 交换即可。
将 snapPoint 设置为您希望快照中心所在的内容偏移量。
将 snapOffset 设置为您想要的 snapPoint 周围的半径,以便捕捉应该发生的位置。
如果您需要知道 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
}
}
}