UICollectionView手势与控件事件冲突的解决方案

2018-07-26  本文已影响1039人  cym_bj

      在日常的开发中我们可能会遇到手势与UI控件事件出现冲突造成监听事件混乱的情况,其实解决方案非常简单。在这里我用点击手势与UICollectionView的item点击事件作为案例对此方法做一下简单的介绍。比如有如下案例:

图中下边绿色的为UICollectionView,红色的控件为其中的item,现在想要实现点击UICollectionView回收键盘,而点击item出现弹窗。我的方法是给UICollectionView添加一个点击的手势,点击回收键盘,然后在UICollectionView的代理方法”- (void)collectionView:(UICollectionView)collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath”中添加item的点击弹窗,代码如下:

#import "ViewController.h"

@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,UIGestureRecognizerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    // 设置界面布局

    [self configureUI];

}

// 界面布局

- (void)configureUI{

    UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(10, 30, [UIScreen mainScreen].bounds.size.width-20, 44)];

    [self.view addSubview:textField];

    textField.borderStyle = UITextBorderStyleRoundedRect;

    textField.backgroundColor = [UIColor whiteColor];

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

    layout.itemSize = CGSizeMake(([UIScreen mainScreen].bounds.size.width - 80)/ 3, 80);

    layout.minimumLineSpacing = 20;

    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(textField.frame)+10, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-CGRectGetMaxY(textField.frame)) collectionViewLayout:layout];

    collectionView.delegate = self;

    collectionView.dataSource = self;

    collectionView.backgroundColor = [UIColor greenColor];

    [self.view addSubview:collectionView];

    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

    // 为collectionView添加手势,点击回收键盘

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(collectionViewClickAction)];

    // 利用代理方法解决后边手势与item点击事件之间的冲突

    tap.delegate = self;

    [collectionView addGestureRecognizer:tap];

}

#pragma mark - UICollectionView的数据源及代理

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return 6;

}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];

    cell.backgroundColor = [UIColor redColor];

    return cell;

}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{

    return UIEdgeInsetsMake(20, 20, 20, 20);

}

// 为了测试增加点击item弹窗的方法

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"测试弹窗" message:@"item被点击了" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

    [alertView show];

}

#pragma mark - 手势相关

// 手势方法,点击回收键盘

- (void)collectionViewClickAction{

    [self.view endEditing:YES];

}

如此判断便很好的解决了点击手势与item点击方法的冲突问题,手势与其他控件的冲突解决方法原理和这个相同,也是利用手势的代理方法进行判断,如果手势执行的视图不是需要的视图就不让其执行。

// 手势代理方法

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    // 判断如果点击的View是UICollectionView就可以执行手势方法,否则不执行

    if ([touch.view isKindOfClass:[UICollectionView class]]) {

        return YES;

    }

    return NO;

}

上一篇下一篇

猜你喜欢

热点阅读