一、创建ScrollView
swift">@objcMembers class LSLottieAnimView : UIView , UIScrollViewDelegate { private var scrollView: UIScrollView = UIScrollView ( ) func addScrollView ( ) { scrollView. showsHorizontalScrollIndicator = false scrollView. isPagingEnabled = true scrollView. frame = CGRect ( x: 0 , y: 0 , width: 100 , height: 100 ) scrollView. delegate = self scrollView. contentSize = CGSize ( width: scrollView. frame. width * CGFloat ( 3 ) , height: scrollView. frame. height) let u1 = UIView ( ) u1. frame = scrollView. boundsu1. backgroundColor = . blacklet u2 = UIView ( ) u2. frame = scrollView. boundsu2. backgroundColor = . greenlet u3 = UIView ( ) u3. frame = scrollView. boundsu3. backgroundColor = . yellowscrollView. addSubview ( u1) scrollView. addSubview ( u2) scrollView. addSubview ( u3) UIApplication . shared. keyWindow? . rootViewController? . view. addSubview ( scrollView) let panGesture = UIPanGestureRecognizer ( target: self , action: #selector ( handlePan ( _ : ) ) ) scrollView. addGestureRecognizer ( panGesture) }
}
二、处理手势
swift">@objc func handlePan ( _ gesture: UIPanGestureRecognizer ) { let scrollView = gesture. view as ! UIScrollView let translation = gesture. translation ( in : scrollView) let count = scrollView. subviews. count - 1 - 1 ; if ( scrollView. contentOffset. x <= 0 && translation. x > 0 ) || ( Int ( scrollView. frame. width) * count <= Int ( scrollView. contentOffset. x) && translation. x < 0 ) { return } if scrollView. isDecelerating || ! scrollView. isScrollEnabled { return } switch gesture. state { case . changed: if scrollView. contentOffset. x - translation. x <= 0 { scrollView. contentOffset. x = 0 } else if scrollView. contentOffset. x - translation. x >= scrollView. frame. width * CGFloat ( count) { scrollView. contentOffset. x = scrollView. frame. width * CGFloat ( count) } else { scrollView. contentOffset. x -= translation. x} case . ended, . cancelled, . failed: let pageIndex = Int ( scrollView. contentOffset. x / scrollView. frame. width) var willPageIndex = pageIndexlet velocity = gesture. velocity ( in : scrollView) if velocity. x > 0 { } else if velocity. x < 0 { if pageIndex < count { willPageIndex = pageIndex + 1 } } else { if translation. x < - scrollView. frame. width / 2 && pageIndex < count { willPageIndex = pageIndex + 1 } else if translation. x > scrollView. frame. width / 2 && pageIndex > 0 { willPageIndex = pageIndex - 1 } } if ( scrollView. contentOffset. x != CGFloat ( willPageIndex) * scrollView. frame. width) { scrollView. setContentOffset ( CGPoint ( x: CGFloat ( willPageIndex) * scrollView. frame. width, y: 0 ) , animated: true ) scrollView. isScrollEnabled = false } default : break } gesture. setTranslation ( . zero, in : scrollView)
}
func scrollViewDidEndScrollingAnimation ( _ scrollView: UIScrollView ) { scrollView. isScrollEnabled = true
}
三、注意事项
swift">1 . 如果需要回弹,只需要修改如下代码即可
if ( scrollView. contentOffset. x <= 0 && translation. x > 0 ) || ( Int ( scrollView. frame. width) * count <= Int ( scrollView. contentOffset. x) && translation. x < 0 ) { return
} case . changed:
scrollView. contentOffset. x -= translation. x
2 . 在调用setContentOffset且animated为true 时,需要考虑将isScrollEnabled设置为false ,等到动画完成后( scrollViewDidEndScrollingAnimation) 将isScrollEnabled恢复到true ,否则在动画期间仍然可以拖拽
3 . 在调用setContentOffset时,如果值和之前相同,则不会触发scrollViewDidEndScrollingAnimation