UICollectionView与UITableView混用手势冲突

前言

最近在重构某个模块,以后别人封装的所谓的基类就像一坨死一样,看见就恶心,相信同行的你们能够明白那种心情。为什么要重构?并不是真的因为它像一坨死,而是因为这个模块是用户使用最频繁的,而且出现了不少bug,最重要的是这bug还是p1级别的致命bug。

曾经经过了几天的压力测试都没有复现出来,但是用户却频繁反馈,这就是决定重构的原因了。重构的界面是这样的:

当UICollectionView中的每个cell放的是一个controller.view而这个controller.view又放一个UITableVIew时,这时候将collectionView的滚动方向设置为横向就可以了。

但是,如果我们设置了bounces为YES,那么右滑返回手势就没有了,怎么办?

实现思路

共使用了四个控制器类:

  • ContentController:手势冲突当前所在的控制器,使用UICollectionView,每个cell对应于一个控制器的view
  • SiteController1:标签一对应的控制器
  • SiteController2:标签二对应的控制器
  • SiteController3:标签三对应的控制器

配置UICollectioView

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// config collection view

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];

layout.itemSize = CGSizeMake(kScreenWidth, kScreenHeight - 64 - tabViewHeight);

layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

layout.minimumLineSpacing = 0;

layout.minimumInteritemSpacing = 0;

self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 64 + tabViewHeight, kScreenWidth, kScreenHeight - 64 - tabViewHeight)

collectionViewLayout:layout];

[self.view addSubview:self.collectionView];

self.collectionView.backgroundColor = kWColor;

self.collectionView.pagingEnabled = YES;

self.collectionView.showsHorizontalScrollIndicator = NO;

[self.collectionView registerClass:[UICollectionViewCell class]

forCellWithReuseIdentifier:kPatientCellIdentifier];

[self.collectionView registerClass:[UICollectionViewCell class]

forCellWithReuseIdentifier:kUnreadCellIdentifier];

[self.collectionView registerClass:[UICollectionViewCell class]

forCellWithReuseIdentifier:kAllCellIdentifier];

// 不能将bounces设置为NO,否则右滑返回手势就没有了

// self.collectionView.bounces = NO;

当我们滚动到标签三时,再滑动就会超出范围,此时会显示部分空白,这体验不太好,不希望可以再滑动了。同样,当滑动到标签一时,再右滑时,不希望显示空白部分,而是触发右滑返回手势。

解决方案

解决方案就是实现UIScrollView的代理方法,当超出屏宽*2时,限制在屏宽*2的位置处。同样,当小于0时,就限制在0处,这样就解决了出现空白的问题。同时,这样就不会关闭用户响应,因此系统的右滑返回手势仍然可以触发。

经过这么一折腾,大家明白如何解决的了吗?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#pragma mark -- UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

// 限制不能超出屏宽*2

if (scrollView.contentOffset.x > 2 * kScreenWidth) {

[scrollView setContentOffset:CGPointMake(2 * kScreenWidth, 0)];

return;

}

// 限制不能超过0

if (scrollView.contentOffset.x < 0) {

[scrollView setContentOffset:CGPointMake(0, 0)];

return;

}

int itemIndex = (scrollView.contentOffset.x +

self.collectionView.hdf_width * 0.5) / self.collectionView.hdf_width;

itemIndex = itemIndex % [self collectionView:self.collectionView numberOfItemsInSection:0];

CGFloat x = scrollView.contentOffset.x - self.collectionView.hdf_width;

NSUInteger index = fabs(x) / self.collectionView.hdf_width;

CGFloat fIndex = fabs(x) / self.collectionView.hdf_width;

if (fabs(fIndex - (CGFloat)index) <= 0.00001) {

// ....切换按钮

}

}

时间: 2024-07-31 14:29:07

UICollectionView与UITableView混用手势冲突的相关文章

UItableView 加手势冲突问题的解决

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { // 获取点击的view的类名 NSLog(@"%@", NSStringFromClass([touch.viewclass])); // 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件 if ([NSSt

iOS 手势冲突

UITableView以及ScrollView不能相迎TouchBegin处理 IOS开发之手势--UIGestureRecognizer 共存 // 关键在这一行,如果双击确定偵測失败才會触发单击 [singleRecognizer requireGestureRecognizerToFail:doubleRecognizer]; 关于UIScrollView不能响应UITouch事件的解决办法 覆盖touch事件 ios的手势操作之UIGestureRecognizer浅析 UITapGes

iOS UICollectionView与UITableView

共同点:都需要接受两个协议 并执行代理方法 不同点:初始化方法不同  UITableVIew可以用alloc 方法初始化 而UICollectionView必须用下面方法初始化 // 初始化瀑布流 UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; [flowLayout setItemSize:CGSizeMake(150,120)]; //设置每个cell显示数据的宽和高必须

iOS自定义全屏返回与tableView左划删除手势冲突解决

当自定义一个navigationController实现全屏右划返回时, 使用起来是不是很爽, 代码如下: - (void)viewDidLoad { [super viewDidLoad]; UIGestureRecognizer *gester = self.interactivePopGestureRecognizer; UIPanGestureRecognizer *panGesTer = [[UIPanGestureRecognizer alloc] initWithTarget:ge

解决右滑返回手势和UIScrollView中的手势冲突

项目中遇到一个页面中是以一个scrollview横向Tab展示两个不同功能的显示,譬如消息和公告功能,但是由于滑动返回手势和scrollview的滑动返回手势冲突了,导致页面不再能够滑动返回.类似的还有图片浏览功能也出现过. iOS系统中,滑动返回手势,其实是一个UIPanGestureRecognizer,系统默认的操作是只有滑动屏幕的左边的某个位置,UIPanGestureRecognizer才会起作用.UIScrollView的滑动手势也是UIPanGestureRecognizer.那在

当ViewPager嵌套在ScrollView/ListView里时,手势冲突如何处理?

有时我们需要将ViewPager嵌套在其他已经含有手势动作的ViewGroup里,如ScrollView,ListView时,会造成手势冲突,如表现为ViewPager向左划时,不小心向上移动了一点距离,ViewPager立刻回弹到原始位置. 主要问题出在ScrollView/ListView作为ViewPager的ParentView,会先接受到触摸信息,而且他们对上下滑动是会做出拦截动作,并接管触摸信息的向下传递,导致ViewPager滑动异常. 先看一种解决方式: public class

简单灵活解决 Viewgroup嵌套 产生的手势冲突问题

转载请标明原文地址:简单灵活解决 Viewgroup嵌套 产生的手势冲突问题 这是接着上一篇Android 下拉刷新上拉加载 多种应用场景 超级大放送(上)的,这里介绍一下怎么 简单灵活解决Viewgroup嵌套产生的手势冲突问题.虽然这里只是以ViewPager为例,但是提供了一种解决此类问题的通用思路. 先来看一下网易新闻客户端的界面效果: 当手势方向为蓝色箭头区域方向时,响应ListView的滑动 当手势方向为黄色箭头区域方向时,响应ViewPager的图片滑动 上一篇实现的Demo效果图

关于iOS抽屉MMDrawerController手势冲突

问题:项目中使用到抽屉控制器MMDrawerController,中间视图设置为TabbarController.现TabbarController上的一个子控制器添加了一个TableController,cell添加侧滑删除,不灵. 原因:抽屉MMDrawerController侧滑手势与cell删除侧滑手势冲突. 解决方案: 将抽屉控制器MMDrawerController侧滑手势范围由全屏改为左侧: 找到MMDrawerController.h类,修改方法 (BOOL)isPointCon

iOS开发 MMDrawerController左右抽屉打开手势与中心视图子视图控制器手势冲突问题的解决方案

MMDrawerController是一个很好用的解决抽屉效果的第三方类,但有时候当我们在中心视图控制器中需要使用手势进行其他操作的时候会产生手势冲突,导致运行效果不符合我们的想象.那么问题来了,该怎么解决冲突问题呢? 下面是我在使用过程中的个人总结: 我的需求: 1.有一个左抽屉和中心视图控制器,从中心视图控制器右滑可以打开左抽屉. 2.中心视图控制器中的TableViewCell可通过滑动手势删除 问题所在: 1.由于删除cell的左滑手势和MMDrawerController的打开右抽屉的