删除 UITableView 单元格之前发出警报 - (UIAlertController) Swift 或 Objective-C

Posted

技术标签:

【中文标题】删除 UITableView 单元格之前发出警报 - (UIAlertController) Swift 或 Objective-C【英文标题】:Alert before deleting UITableView cell - (UIAlertController) Swift or Objective-C 【发布时间】:2013-01-12 20:39:27 【问题描述】:

我想删除一个表格视图单元格,但在该操作发生之前,我想给用户一个警报视图。我得到了这个:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
                                                        message:@"Are you sure?"
                                                       delegate:self
                                              cancelButtonTitle:@"NO"
                                              otherButtonTitles:@"YES", nil];
        [alert show];

        [self.array removeObjectAtIndex:indexPath.row];//or something similar to this based on your data source array structure
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
    if([title isEqualToString:@"Nee"])
    
        NSLog(@"Nothing to do here");
    
    else if([title isEqualToString:@"Ja"])
    
        NSLog(@"Delete the cell");

    

但是现在当我在单元格上向右滑动并出现删除按钮时,我没有看到 AlertView。当我按下删除按钮时,我只会得到 AlertView。当我按下删除按钮时,会出现消息,但单元格已被删除。

如何做到这一点?所以当我滑动时会有一个 AlertView。

【问题讨论】:

如果与 Xcode 无关,请勿使用“Xcode”标记内容。 @H2CO3:你每天多久写一次? (开个玩笑。) @MartinR 几乎总是在需要时:P @MartinR 当问题与 IDE 无关时,我无法告诉你有多少个问题被标记为 xcode 【参考方案1】:

关于顺序,一切都很好。 commitEditingStyle 只会在删除按钮被按下时被调用。关键是您实际上是在响应警报之前删除对象。改成这样:

将此添加到.m 文件中@implementation 之前:

@interface PutYourViewControllerClassNameHere
@property (strong, nonatomic) NSIndexPath *indexPathToBeDeleted;
@end

然后:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    if (editingStyle == UITableViewCellEditingStyleDelete) 

        self.indexPathToBeDeleted = indexPath;

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
                                                        message:@"Are you sure?"
                                                       delegate:self
                                              cancelButtonTitle:@"NO"
                                              otherButtonTitles:@"YES", nil];
        [alert show];
        // do not delete it here. So far the alter has not even been shown yet. It will not been shown to the user before this current method is finished.     
    


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

    // This method is invoked in response to the user's action. The altert view is about to disappear (or has been disappeard already - I am not sure) 

    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
    if([title isEqualToString:@"NO"])
    
        NSLog(@"Nothing to do here");
    
    else if([title isEqualToString:@"YES"])
    
        NSLog(@"Delete the cell");

        [self.array removeObjectAtIndex:[self.indexPathToBeDeleted row]];
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:self.indexPathToBeDeleted] withRowAnimation:UITableViewRowAnimationFade];
    

编辑:这应该编译,尽管可能有轻微的语法错误。 一般假设:您只处理一个部分。至少只有一个部分在删除是可能的。

【讨论】:

您可以使用(滥用?)UIViewtag 属性将选定的行传递给警报委托:alert.tag = indexPath.row 在该代码之后,我在 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex: Use of undeclared identifier 'indexPath';你的意思是“NSIndexPath”吗?和未知的接收者'tableView';你的意思是“UITableView”吗? @MartinR,很好的主意,使用(ab-)标签。 @user1883396 这正是我所说的代码不会编译的意思。 indexPath 不在 clickedButtonAtIndex: 范围内。等一下。我会为您检查文档,然后对我的答案进行工作/编译编辑。 @HermannKlecker 编辑后,我在日志中收到此错误:2013-01-12 22:16:29.421 Myappname[4703:c07] 此处无事可做 2013-01-12 22:16: 32.177 Myappname[4703:c07] 删除单元格 2013-01-12 22:16:32.179 Myappname[4703:c07] *** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'*** -[__NSPlaceholderArray initWithObjects: count:]: 尝试从 objects[0]' 中插入 nil 对象' 我们快到了。 NO 按钮仅适用于 YES 按钮会出现此错误。【参考方案2】:

ios 8 +

iOS 8 引入了UIAlertController。这允许您在完成块中而不是在委托方法中编写删除和取消代码(根据旧的 UIAlertView-clickedButtonAtIndex)。

斯威夫特 3

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete 
        let alertController = UIAlertController(title: "Warning", message: "Are you sure?", preferredStyle: .alert)

        let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler:  (action) in
            self.tableView.deleteRows(at: [indexPath], with: .fade)
        )
        alertController.addAction(deleteAction)

        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
        alertController.addAction(cancelAction)

        present(alertController, animated: true, completion: nil)
    

Objective-C

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Warning" message:@"Are you sure?" preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) 
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        ];
        [alertController addAction:deleteAction];

        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 
            NSLog(@"Don't do anything");
        ];
        [alertController addAction:cancelAction];

        [self presentViewController:alertController animated:YES completion:nil];
    

【讨论】:

【参考方案3】:

当删除操作已经发生时,您正在调用警报....

把它放进去:

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

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Waarschuwing!"
                                                message:@"Weet je zeker dat je het vak: lalaal wilt verwijderen?"
                                               delegate:self
                                      cancelButtonTitle:@"Nee"
                                      otherButtonTitles:@"Ja", nil];
[alert show];

当单元格被滑动并且在按钮被按下之前,这将调用警报。

【讨论】:

谢谢!那行得通。现在需要修复 UIAlertview。我应该在 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex ??? 这个委托方法用于处理点击按钮的事件:“Nee”,“Ja”,命名它......这是一个用switch(buttonIndex)处理这个的好方法。如果是 1(因为“Ja”按钮是第二个),只需删除单元格。【参考方案4】:

iOS 9.0 和 Swift 2.3

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 

        let alertController = UIAlertController(title: "Warning!", message: "You're about to delete this stuff right meow.", preferredStyle: .Alert)
        let delete = UIAlertAction(title: "Do it.", style: .Destructive, handler:  action in

            tableView.beginUpdates()
            //delete from your datasource!
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            tableView.endUpdates()
        )

        let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler:  action in

            //this is optional, it makes the delete button go away on the cell
            tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
        )

        alertController.addAction(delete)
        alertController.addAction(cancel)
        presentViewController(alertController, animated: true, completion: nil)
    

【讨论】:

以上是关于删除 UITableView 单元格之前发出警报 - (UIAlertController) Swift 或 Objective-C的主要内容,如果未能解决你的问题,请参考以下文章

如何从uitableview单元格中删除单元格

删除 UITableView 中的最后一个单元格时索引超出范围

如果 UITableView 没有条目,则显示警报

使带有删除按钮的 UITableView 对所有单元格可见

删除多个单元格后,uitableview 添加了一些行

为啥我的 UITableView 单元格在滚动时重叠?