如何避免在 UITableViewCell 上滑动删除调用 setEditing

Posted

技术标签:

【中文标题】如何避免在 UITableViewCell 上滑动删除调用 setEditing【英文标题】:How to avoid swipe to delete calling setEditing at the UITableViewCell 【发布时间】:2011-06-22 09:47:03 【问题描述】:

我知道,当我实现tableView:willBeginEditingRowAtIndexPath:tableView:didEndEditingRowAtIndexPath:时,滑动删除不会在我的UITableViewController(作为UITableView的代表)调用setEditing:animated:

我有一个自定义的UITableViewCell 实现,它在进入编辑模式时会进行一些 UI 重新排列。我想变得聪明一点,并在表格视图单元实现本身的setEditing:animated: 中实现这些更改(这显然是有道理的)。

但是,当滑动删除时,我仍然在我的表格视图单元格实现中接到setEditing:animated: 的电话。而且我没有参数告诉我我正在刷卡。调用堆栈也没有显示我自己的任何方法,这些方法可以让我有机会做某事。它表明setEditing:animatedUITableView 处被调用。唯一明显的是,它没有在委托(在这种情况下是我的控制器)处调用。

当然,我可以在tableView:willBeginEditingRowAtIndexPath: 的单元格中设置一个标志,告诉它下一个setEditing 调用将用于滑动,但这听起来不太好。

编辑:它甚至不起作用,因为不能保证tableView:didEndEditingRowAtIndexPath: 被调用,所以我无法设置标志。

任何想法如何优雅地解决这个问题?

【问题讨论】:

我不确定我是否理解正确。所以你还是想在你的 UITableViewCell 的 setEditing:animated: 中做点什么,对吧?如果没有,这个链接有帮助吗? ***.com/questions/969313/… 我想启用滑动删除。但我希望能够区分“真实”编辑模式和为滑动删除设置的“伪”编辑模式。在UITableViewDelegate 中我可以区分两者,因为在滑动删除时不会调用setEditing:animated:。但是,我无法在 UITableViewCell 实现中有所作为。还是我不知何故? 【参考方案1】:

我认为 UITableViewCell 的willTransitionToState: 实例方法可能是您正在寻找的。像这样的:

- (void)willTransitionToState:(UITableViewCellStateMask)state

    if (state == UITableViewCellStateShowingDeleteConfirmationMask) 
        swipedToDelete = YES; // BOOL ivar
    


- (void)setEditing:(BOOL)editing animated:(BOOL)animated

    if (swipedToDelete) 
        // do your stuff, or don't
    

是吗?

【讨论】:

是的,这解决了在单元格上获得通知以进行滑动的问题。谢谢!可以在 else 分支中的 willTransitionToState 中设置标志。但是仍然存在一个问题:如果我开始在表格视图中进行编辑,所有单元格都会收到 setEditing 调用。此外,当我结束编辑但不是在这种情况下:我滑动删除获取“删除”按钮,然后在我的表格视图中按“编辑”。然后细胞不会接到setEditing 的电话。这真的很奇怪。有什么想法吗? 请注意:调试时的问题是单元格的setEditing:animated: 是通过UITableViewControllersetEditing:animated: 实现触发的(在我的例子中是[super setEditing:editing])。所以,我只能猜测单元格被通知了,因为有一个单元格带有editing == YES 可能苹果在联系人应用程序中遇到了同样的问题。他们通过将“编辑”按钮更改为“完成”按钮来“解决”它,因此无法从删除确认状态进入编辑模式。 如果加上[super willTransitionToState:state];在您的代码中,您保留了常见的单元格行为。以防万一有人(像我一样)复制并粘贴此方法并想知道为什么单元格中的图标消失了.. ;) 正如拉斐尔所说,添加 [super willTransitionToState:state];【参考方案2】:

我知道这可能已经完成了,但提出的解决方案似乎不是一个完整的简单答案,它们似乎也没有提供好的示例代码,所以我想我会添加我的答案。

给你的类添加一个私有实例变量:

@implementation MyTableViewController 
    BOOL _cellSwiped;

重写 setEditing 方法以查找 _cellSwiped 变量,并且仅在我们不滑动时传播。人们似乎缺少的部分是 _cellSwiped 需要重置为 NO 否则您将永远无法在刷卡后使用编辑按钮!

- (void) setEditing:(BOOL)editing animated:(BOOL)animated 
    if (!_cellSwiped) 
        [super setEditing:editing animated:animated];
     else if (!editing) 
        _cellSwiped = NO;
    

最后,添加这个方法覆盖来检测滑动:

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath 
    _cellSwiped = YES;

【讨论】:

【参考方案3】:

我做的是这样的:

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

    cellSwiped = YES;
    self.editing = NO;

然后在

- (void)setEditing:(BOOL)editing animated:(BOOL)animated 

方法我只是检查是否设置了 cellSwiped ivar 并相应地修改 UI。

【讨论】:

这正是我在我的问题中提到的。但是,这并不可靠(请参阅问题)【参考方案4】:

这是一个老问题,但我想知道为什么似乎没有人知道showingDeleteConfirmation 属性内置在UITableViewCell 中(自ios 2.0 起):

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

    [super setEditing:editing animated:animated];

    BOOL reallyEditing = editing && !self.showingDeleteConfirmation;
    // [...]

无需覆盖-willTransitionToState: 并手动跟踪状态。

【讨论】:

此时,showingDeleteConfirmation 实际上是 NO,并在 setEditing:animated: 调用后设置。【参考方案5】:
- (void)tableView:(UITableView *)tableview commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

    if(editingStyle != UITableViewCellEditingStyleDelete) 
       // add code here

    

调用时,该方法会执行以下操作

UITableViewCellEditingStyleNone,
UITableViewCellEditingStyleDelete,
UITableViewCellEditingStyleInsert

如果你不想要滑动选项,你可以在委托方法中设置 bool 变量

- (void)willTransitionToState:(UITableViewCellStateMask)state

willTransitionToState 会在之前被调用

commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:

【讨论】:

以上是关于如何避免在 UITableViewCell 上滑动删除调用 setEditing的主要内容,如果未能解决你的问题,请参考以下文章

如何来回移动 UITableViewCell 以显示它可以滑动?

UITableViewCell 标签显示有很少的上滑动画

滑动手势在 UITableViewCell 中不起作用

UITableViewCell 如何检测用户向左或向右滑动?

如何自定义滑动 UITableViewCell 时显示的删除按钮

滑动 UITableViewCell