解決cell滑動刪除和scrollView左右滑動之間的沖突

項目需求是這樣的:需要在scrollView上加載三個TableView,第一個TableView的cell又要實現左滑刪除功能。最后的解決效果圖如下:

效果圖.gif

首先分析需求:我是需要在第一個TableView上實現左滑刪除cell功能,這需求直接把網上的給出的解決方案:(通過設置手勢代理,實現view相應多個手勢)給拒之門外。
所以我采取了個比較笨的方法:
1、一上來把scrollView的enable屬性設置成no,然后給當前view加一個屏幕邊緣滑動手勢,通過判斷這個手勢的移動來動態改變scrollView的偏移量,當手勢結束的時候,判斷scrollView的偏移量:如果偏移量大于屏幕一半,則打開scrollView的enable屬性,關閉手勢的enable屬性;


// 如果是第一頁的話:
// 判斷偏移量:
// 如果偏移量>屏幕寬一半:scrollView偏移量為當前scrollView的寬度,scrollView響應,手勢不響應

// 如果不是第一頁的話:
// scrollView一直相應
- (void)panGrAction:(UIScreenEdgePanGestureRecognizer *)sender
{
//    NSLog(@"====");
    
    if (self.scrollView.contentOffset.x<self.view.bounds.size.width) {
        CGPoint first = [sender translationInView:self.view];
        self.scrollView.contentOffset = CGPointMake(fabs(first.x), 0);
    }
    if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"開始");
    }else if (sender.state == UIGestureRecognizerStateEnded){
        NSLog(@"結束");
        NSInteger count = self.scrollView.contentOffset.x / self.view.bounds.size.width;
        
        CGFloat rest_point = self.scrollView.contentOffset.x - (self.view.bounds.size.width * count);
        if (rest_point > self.view.bounds.size.width * 0.5) {
            CGFloat off_x;
            if (self.scrollView.contentSize.width > self.view.bounds.size.width * (count+1)) {
                off_x = self.view.bounds.size.width * (count+1);
            }else{
                off_x = self.view.bounds.size.width * count;
            }
            self.scrollView.contentOffset = CGPointMake(off_x, 0);
        }else{
            self.scrollView.contentOffset = CGPointMake(self.view.bounds.size.width * count, 0);
        }
        
        
        if (!(self.scrollView.contentOffset.x<self.view.bounds.size.width)) {
            self.scrollView.scrollEnabled = YES;
            self.panGr.enabled = NO;
        }
    }
}

2、在通過監聽scrollView的結束減速方法監聽scrollView的偏移量,當發現scrollView偏移到第一頁的時候,再關閉scrollView的enable屬性,打開手勢的enable屬性。


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    NSLog(@"結束減速");
    if ((self.scrollView.contentOffset.x<self.view.bounds.size.width)) {
        self.scrollView.scrollEnabled = NO;
        self.panGr.enabled = YES;
    }
}

擴展1

自定義設置cell的滑動刪除
從iOS8以后,我們可以采取下面的這個方法

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

-(NSArray<UITableViewRowAction*>*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    UITableViewRowAction *rowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"取消收藏" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSLog(@"收藏點擊事件,%ld", indexPath.row);
    }];
    
    UITableViewRowAction *rowAction2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"頂置" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSLog(@"頂置按鈕點擊事件,%ld", indexPath.row);
    }];
    
    rowAction.backgroundColor = kRandomColor;
    
    NSArray *arr = @[rowAction,rowAction2];
    
    return arr;
}

擴展2

如果你的需求是最后一個TableView實現cell的滑動刪除,那么直接實現一個代理方法,并且在scrollView定義的時候,加上兩句代碼,即可完成

// 重寫下面方法,為了讓Scrollview可以識別多個手勢
// 此方法返回YES時,手勢事件會一直往下傳遞,不論當前層次是否對該事件進行響應
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return gestureRecognizer.state != 0 ? YES : NO;
}

// scrollView需要設置的地方
        [scrollView setDelaysContentTouches:NO];
        [scrollView setCanCancelContentTouches:NO];

最后demo地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容