更改长按 uiTableView IOS 上的单元格选择

Posted

技术标签:

【中文标题】更改长按 uiTableView IOS 上的单元格选择【英文标题】:Change Selection of Cell on Long Press uiTableView IOS 【发布时间】:2014-08-28 19:45:23 【问题描述】:

在 uitableview 上正常选择单元格工作正常。但是,当为单元格调用长按事件时,它会再次选择先前选择的单元格。例如,如果用户选择了第一个单元格,然后长按第二个单元格,则为第二个单元格调用长按事件,但选择会再次返回到第一个单元格。

这是我的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

if (cell == nil) 

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    //add longPressGestureRecognizer to your cell
    UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleLongPress:)];
    //how long the press is for in seconds
    lpgr.minimumPressDuration = 1.0; //seconds
    [cell addGestureRecognizer:lpgr];




return cell;


-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer


CGPoint p = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
if (indexPath == nil) 
    NSLog(@"long press on table view but not on a row");

else

    if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
    
        NSLog(@"long press on table view at row %ld", (long)indexPath.row);

        editViewController *editView = [self.storyboard instantiateViewControllerWithIdentifier:@"editView"]; //dont forget to set storyboard ID of you editViewController in storyboard
        [self.navigationController pushViewController:editView animated:YES];
    



【问题讨论】:

将手势分配代码移到if(cell == nil)块之外,看看会发生什么。 【参考方案1】:

您遇到的问题似乎源于将单元格标记为选中和处理该单元格上的长按手势事件是分开的。我对您的问题的解释是,您有一个带有单选(而不是多选)的表格视图,并且您希望单元格通过正常点击以选择动作以及识别长按手势来“选中”。但是 - 虽然您希望通过长按手势选择单元格,但您希望长按导致与通过正常点击进行选择不同的操作(例如,如果用户点击要启动视图控制器 A 的单元格,但如果用户长按您想要启动视图控制器 B 的单元格,并且在这两种情况下您都希望表格将单元格视为“已选中”)...如果您想要的与此不同,请告诉我,我可以更新答案。

这对于表格视图来说不是很常见的行为,但我们可以通过稍微修改您的代码来使其工作:

首先定义一个属性来跟踪是否发生长按:

@property (assign, nonatomic) BOOL longPressActive;

然后在您的 handleLongPress 方法中,告诉表格选择行:

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer


    CGPoint p = [gestureRecognizer locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
    if (indexPath == nil) 
        NSLog(@"long press on table view but not on a row");
    
    else
    
        if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
        
            NSLog(@"long press on table view at row %ld", (long)indexPath.row);
            self.longPressActive = YES;

            [self.tableView selectRowAtIndexPath:indexPath
                                        animated:NO
                                  scrollPosition:UITableViewScrollPositionNone];

        else if (gestureRecognizer.state == UIGestureRecognizerStateEnded ||
                  gestureRecognizer.state == UIGestureRecognizerStateCancelled) 
            self.longPressActive = NO;
    


最后,在您的表格视图委托方法中,定义您在选择后所期望的行为。请注意,在示例中,长按任何单元格将导致显示相同的视图控制器。为了以不同的方式设置视图控制器,您可以遵循类似于我在your prior question 中的回答的过程,或者您可以在实例化后将特定于行的数据传递给 editViewController。

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

    if (self.longPressActive)  //Perform action desired when cell is long pressed

        editViewController *editView = [self.storyboard instantiateViewControllerWithIdentifier:@"editView"];
        [self.navigationController pushViewController:editView animated:YES];

    else  //Perform action desired when cell is selected normally

        //Your code here
    

 

希望这会有所帮助。

【讨论】:

我使用 TableView 来显示核心数据实体,现在如果用户点击一个单元格我想启动 EditViewController 但如果用户长按该单元格我想启动该单元格的详细信息,所以重要的是wاich 单元格被按下或哪个单元格被长按,因为我想将选定的单元格(通过按下)传递给 EditViewController 并将选定的单元格(通过长按)传递给 DetailsViewController 上面的代码应该做到这一点。但是,为了澄清,您不应该将单元格传递给 EditViewController 或 DetailsViewController,您应该将引用传递给您的核心数据实体托管对象。传递单元本身会破坏 MVC 范式。 我现在,这是我的具体问题:如何在长按时更改单元格的选择? 在我的回答中的handleLongPress 方法中,我包含了通知表格单元格应该被选中的代码:[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 这不适合你吗?需要注意的一点是,调用该方法会更改单元格的选择状态,但它不会调用tableView: didSelectRowAtIndexPath: 委托方法……所以如果你也想调用它,你应该直接调用。

以上是关于更改长按 uiTableView IOS 上的单元格选择的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 自定义单元格更改值 iOS 9

点击或长按单元格下方

如何在 iPad 上的 iOS 7 上的 UITableView 单元格右侧绘制图像?

iOS - UITableView 正确刷新表?

Swift:无法长按拖动单元格到 UICollectionViewController 和 UITableView 中的空白部分

iOS UITableView:更改表格的背景颜色会覆盖单元格的背景颜色