UITableview上gesture操作cell的技术实现

朱欣荣
2023-12-01

在一个UITableview的对象上,需要实现每一个cell上的手指滑动操作去对该cell进行删除或者打勾。

在编辑状态下,操作为删除该cell;在非编辑状态下,操作为打勾。

首先,在自定义的UITableviewCell类中,加入UIPanGestureRecognizer *panGestForDelete,*panGestForCheck;两个对象,分别完成删除或打勾操作。

接着,在该cell类中声明delegate,使用delegate方法将该cell传输出来,传输到uitableview对象中。

最后,在UIPanGestureRecognizer对象的selector实现中,对UIGestureRecognizerStateBegan,UIGestureRecognizerStateChanged和UIGestureRecognizerStateEnded三个状态下的gesture做出判断。

因为每一个cell上有独立的gesture,所以可以直接得出cell对象,对其进行操作。

另外,在UIPanGestureRecognizer操作过程中,UITableview还能滚动,所以再借助delegate到UITableview中将其scrollEnabled设置为NO。等到UIPanGestureRecognizer结束时再将其还原为YES。

这是第一个实现方法。它能实现功能。

但是,它有不足的地方。它在每一个cell上增加对象,客观上加大内存占用量;还有大量使用delegate回调操作,客观上增加CPU的使用率;再有就是代码复杂了点。

换一种思路,我们是可以在UITableview的对象上直接上UIPanGestureRecognizer对象的。只是每一个gesture操作时,需要判读到是在哪个cell上操作的。

首先,在自定义的UITableview类中,加入   UIPanGestureRecognizer*_panGestForDeleteAndCheck;对象,联合self.editing实现删除或者打勾操作。

接着,在UIPanGestureRecognizer对象的selector实现代码中,在UIGestureRecognizerStateBegan状态时,就根据CGPoint location = [recognizer locationInView:self];得到触摸点的位置,根据位置使用NSIndexPath *indexPath = [self indexPathForRowAtPoint:location];方法得到表的cell。

代码如下所示:

    if(recognizer.state == UIGestureRecognizerStateBegan) {

        // if the gesture hasjust started, record the current centre location

        CGPoint location =[recognizer locationInView:self];

       

        //Get thecorresponding index path within the table view

        NSIndexPath *indexPath= [self indexPathForRowAtPoint:location];

 

        //Check if index pathis valid

        if(indexPath)

        {

            //Get the cell outof the table view

            _originalCell =(XYShpCell *)[self cellForRowAtIndexPath:indexPath];

           

            _originalCellFrame=  _originalCell.frame;

           

           _originalShpItem=[self.dsItems objectAtIndex:indexPath.row];

           

            _originalCellCenter =_originalCell.center;

           

            self.scrollEnabled= NO;

        }

        else

        {

            _originalCell=nil;

            return;

        }

       

    }

 

因为已经在UITableview对象中操作了,所以可以直接将scrollEnabled设置为NO。

 

这个方法实现起来简单一些,内存占用少很多,最起码cell对象没那么庞大了。

 

在这两个方法中,都需要实现这个delegate方法。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizershouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer

{

    return YES;

}

这是因为uitableview上也有很多gesture,需要一起运行。

 

在这两个方法中,处理cell的方法也是一致的,只是第二种方法不需要调用delegate来对cell操作了。

- (void)markCellToOpers:(XYShpCell *)cell

{

       if (self.editing) {

        if(_originalShpItem.state ==-1||_originalShpItem.state==0) {

           _originalShpItem.state = _originalShpItem.state == -1 ? 0 : -1;

           

            if(_originalShpItem.state == -1) {

                NSDictionary*attributes = @{NSStrikethroughStyleAttributeName: [NSNumbernumberWithInt:NSUnderlineStyleSingle]};

               cell.itemTextField.attributedText = [[NSAttributedString alloc]initWithString:_originalShpItem.text attributes:attributes];

                cell.itemTextField.placeholder=_shpItemTipString2;

               

                [selfdoDeleteItem:_originalShpItem];

               

            } else if(_originalShpItem.state == 0) {

               cell.itemTextField.attributedText = nil;

               cell.itemTextField.text = _originalShpItem.text;

               cell.itemTextField.placeholder=_shpItemTipString;

               

                [selfundoDeleteItem:_originalShpItem];

            }

        }

       

    }

    else

    {

        if(_originalShpItem.state ==1||_originalShpItem.state==0) {

           _originalShpItem.state = _originalShpItem.state == 1 ? 0 : 1;

           

            cell.accessoryType= (_originalShpItem.state == 1) ? UITableViewCellAccessoryCheckmark :UITableViewCellAccessoryNone;

           cell.editingAccessoryType = (_originalShpItem.state == 1) ?UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

           

            [selfcheckItem:_originalShpItem];

        }

    }

 

}

 

无论UITableview在编辑状态下,还是非编辑状态下,每个cell上的勾(如果有勾的话)都需要显示出来。因此,这里需要将     cell.accessoryType和cell.editingAccessoryType都设置一下。

这里删除操作是将文字画横线,然后批量删除,所以需要将该方法也实现。

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableVieweditingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

{

   return UITableViewCellEditingStyleNone;

}

不要系统自带的编辑功能按钮如delete和insert按钮。

 

 

 类似资料: