删除 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];
编辑:这应该编译,尽管可能有轻微的语法错误。 一般假设:您只处理一个部分。至少只有一个部分在删除是可能的。
【讨论】:
您可以使用(滥用?)UIView
的 tag
属性将选定的行传递给警报委托: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的主要内容,如果未能解决你的问题,请参考以下文章