The solution to the conflict between gestures and control events

In daily development, we may encounter a situation where gestures and UI control events conflict with event listeners, but the solution is actually very simple. Here I use the click gesture and the item click event of UICollectionView as a case to make a brief introduction to this method. For example, there is the following case:
write picture description here
the green one at the bottom of the figure is UICollectionView, and the red control is the item in it. Now I want to click UICollectionView to recover the keyboard, and click the item to display a pop-up window. My method is to add a click gesture to UICollectionView, click to recycle the keyboard, and then add item click popup in UICollectionView's proxy method "- (void)collectionView:(UICollectionView )collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath", the code is as follows :


- (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];
}

But after executing the above code, you will find that the method "- (void)collectionView:(UICollectionView )collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath" will not be executed when the item is clicked, and clicking on the item will still execute the gesture method to recycle the keyboard, so in Here, we need to use the proxy method of gesture to judge. If the clicked view is UICollectionView, the gesture is executed, otherwise, the gesture is not executed, so the following method is added to the above code

// 手势代理方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    // 判断如果点击的View是UICollectionView就可以执行手势方法,否则不执行
    if ([touch.view isKindOfClass:[UICollectionView class]]) {
        return YES;
    }
    return NO;
}

This judgment solves the conflict between click gestures and item click methods. The principle of conflict resolution between gestures and other controls is the same as this. It is also judged by the proxy method of gestures. If the view executed by the gesture is not the desired view, Don't let it execute.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325993340&siteId=291194637