当前位置:网站首页>UIScrollView(UICollectionView)禁止横向和竖向同时滑动
UIScrollView(UICollectionView)禁止横向和竖向同时滑动
2022-07-23 07:52:00 【Daniel_Coder】
今天遇到这么一个需求,我们有个界面显示很多队员以及他们的各项得分情况,界面是用UICollectionView做的,配上自定义的layout,支持横向和竖向滑动,更支持对角线滑动,当在对角线方向滑动的时候,横向和竖向都在滑动。
现在的要求是禁止对角线滑动,要么横向,要么竖向滑动。
首先在查阅苹果文档后,知道有这么一个属性能够做一些控制。
// default NO. if YES, try to lock vertical or horizontal scrolling while dragging
open var isDirectionalLockEnabled: Bool If this property is
false, scrolling is permitted in both horizontal and vertical directions. If this property istrueand the user begins dragging in one general direction (horizontally or vertically), the scroll view disables scrolling in the other direction. If the drag direction is diagonal, then scrolling will not be locked and the user can drag in any direction until the drag completes. The default value isfalse
该属性值为false的时候:
- 支持横向和竖向两个方向的滑动。
当该属性为true的时候:
- 如果用户刚开始滑动的时候更趋近于横向滑动的话,那么就禁止竖向的滑动;
- 如果用户刚开始滑动的时候更趋近于竖向滑动的话,那么就禁止横向的滑动;
- 如果用户沿着对角线滑动,那么该属性就失效了,两个方向都可滑动。
用了这个属性后,大概率会减少一开始两个方向同时滑动的问题,但是不够完美。我们还需要处理在沿对角线的滑动方式。
下面给UIScrollView添加一些扩展方法及属性,来处理沿对角线的滑动的问题。
extension UIScrollView {
enum ScrollDirection {
case none // 未滑动
case diagonal // 对角线方向
case horizontal // 横向
case vertical // 竖向
}
// 记录每次开始滑动的时候初始偏移量
private var initialContentOffset: CGPoint {
get {
let key: UnsafeRawPointer! = UnsafeRawPointer.init(bitPattern: "initialContentOffset".hashValue)
let obj: CGPoint? = objc_getAssociatedObject(self, key) as? CGPoint
return obj ?? .zero
}
set {
let key: UnsafeRawPointer! = UnsafeRawPointer.init(bitPattern: "initialContentOffset".hashValue)
objc_setAssociatedObject(self, key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
func setInitialContentOffset(_ offSet: CGPoint) {
initialContentOffset = offSet
}
// 获取滑动方向
func scrollDirection() -> ScrollDirection {
var direction: ScrollDirection = .none
if contentOffset.x != initialContentOffset.x && contentOffset.y != initialContentOffset.y {
direction = .diagonal
} else if contentOffset.x != initialContentOffset.x {
direction = .horizontal
} else if contentOffset.y != initialContentOffset.y {
direction = .vertical
} else {
direction = .none
}
return direction
}
// 沿单个轴滑动
func scrollAlongOneAxis() {
let direction = scrollDirection()
if direction == .diagonal {
var newOffset: CGPoint = .zero
if abs(contentOffset.x) > abs(contentOffset.y) {
newOffset = CGPoint(x: contentOffset.x, y: initialContentOffset.y)
} else {
newOffset = CGPoint(x: initialContentOffset.x, y: contentOffset.y)
}
setContentOffset(newOffset, animated: false)
}
}
}- 首先通过枚举定义几个滑动方向,包括了横向、竖向、对角线方向。
- 设置initialContentOffset,用来记录每次将要移动时的初始偏移量。
- 通过scrollDirection()方法,来判断用户在哪个方向上移动。
- 最后调用scrollAlongOneAxis()方法进行单轴方向移动。
扩展方法和属性介绍完了,那么在具体的项目中怎么用呢?
第一步:
给UICollectionView或者UIScrollView设置isDirectionalLockEnabled为true,这样让系统帮我们处理一些,减少scrollAlongOneAxis()方法中if条件下的代码执行次数。
第二步:
在UIScrollViewDelegate代理方法scrollViewWillBeginDragging中调用setInitialContentOffset()方法设置初始偏移量。
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
scrollView.setInitialContentOffset(scrollView.contentOffset)
}第三步:
在UIScrollViewDelegate代理方法scrollViewDidScroll中调用scrollAlongOneAxis()方法实现单轴方向滑动。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
scrollView.scrollAlongOneAxis()
}以上三步即可实现我们想要的每次只能单个方向滑动的问题,如果有更好的方法,还请路过的朋友指点一二。
如果觉得文章对你有用,不妨给个赞,关注一下,更多好用文章还在继续更新中。
本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,还请标明出处。
边栏推荐
- pingbanceshi
- Image processing 6: top level file
- Ansible first knowledge of learning one
- rtx3080ti和rtx3080差距 3080和3080ti参数对比
- Remember that a vulnhub target plane exercise successfully won the root permission
- Comment creo 9.0 modifie - t - il rapidement le système de coordonnées Cao?
- Day 12 notes
- overlayfs源代码解析
- C: readonly and Const
- 背包问题详解
猜你喜欢
随机推荐
iQOO 10 Pro和vivo X80 Pro区别 哪个好详细参数配置对比
判断一个对象是否是空对象的处理办法
配置firecracker流程即踩坑记录
数千个数据库、遍布全国的物理机,京东物流全量上云实录 | 卓越技术团队访谈录
rtx3080相当于gtx什么显卡 rtx3080显卡什么水平 rtx3080显卡怎么样
Day 11 notes
Notes on the sixth day
FPGA:ov7725摄像头通过VGA/HDMI显示RGB565格式的图像
200 lines of code, in-depth analysis of the principle and implementation of dynamic calculation diagram
机器学习入门难?说说我是如何快速开始机器学习入门的!
赛扬n5095处理器怎么样 英特尔n5095核显相当于什么水平
Excel essay record
Medium range
酷睿i5 12490f和i5 12600k差距大吗
NR Modulation 5
天玑1100相当于骁龙多少处理器 天玑1100相当于骁龙多少 天玑1100怎么样
GRE,MGRE的詳細了解;OSPF基礎配置知識
Image processing 5: expansion
《乔布斯传》英文原著重点词汇笔记(十五)【 chapter fourteen】
excel随笔记录









