一、页面基本结构
- 底层是一个垂直的scrollView,页面顶部是一个imageView。底部是一个tableView。如图:

二、思路一
- 首先想到的是,既然是滚动视图,我们可以通过滚动视图的可滚动属性来实现吗?最开始,顶层具体业务的tableView禁止滚动。然后,根据事件响应链,滚动事件将由底层ScrollView接收和处理。达到最大偏移量后,底层ScrollView禁止滚动,顶层tableView同时打开,顶层可以滑动。不幸的是,现实是残酷的。
- 因此,当偏移量达到临界值时,由于可滚动属性和最大偏移量的设置(将其中一个控件的可滚动属性 isScrollEnabled 设置为 false ),滚动手势将被截断,需要再次拖动才能继续滚动。显然,这种效果是不可接受的。
三、思路二
- 使用定制手势。但是由于UIScrollView具有弹性效果,普通的滑动手势无法做到这一点,因此有必要引入UIDynamic仿真力场来实现阻尼效果。想了想,虽然在某种程度上是可行的,但是对于一个联动滑动来说,做这么多事情还是比较繁琐的,自定义手势的模拟弹性效果和原生ScrollView的效果可能还是有一定差距的,所以我选择放弃。
四、思路三
-
回到第一个想法,除了边界位置会阻挡联动滚动,其他效果还是有可能的,那么能否通过手段解决这个问题呢?既然能写到这里,毫无疑问,绝对有可能。通过手势渗透,即滑动手势可以同时作用于底部的ScrollView和上部的tableView,并同时控制它们的滚动。通过底层滚动视图实现手势识别协议,同时响应滚动事件。
-
1、先实现底层 scrollView 的协议方法 :shouldRecognizeSimultaneouslyWith方法,表示能同时识别两个gesture。
//MARK: - UIGestureRecognizerDelegate
extension UIScrollView: UIGestureRecognizerDelegate {
//手势穿透,是否允许两个手势识别器同时识别手势(滑动手势可以同时作用于底部的ScrollView和上部的 tableView,并同时控制它们的滚动)
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
- 2、接着分别在底层容器和上层业务中实现滚动视图的代理方法 func scrollViewDidScroll(_ scrollView: UIScrollView),分别控制它们的可滚动状态和偏移量,从而达到目的。部分实现如下:


961

被折叠的 条评论
为什么被折叠?



