如何检测在表视图委托方法中调用的 UIActionSheet 按钮的点击?

Posted

技术标签:

【中文标题】如何检测在表视图委托方法中调用的 UIActionSheet 按钮的点击?【英文标题】:How do I detect the tap of a UIActionSheet button called inside a table view delegate method? 【发布时间】:2014-02-25 22:31:53 【问题描述】:

好的,我有一个带有 UIActionSheet 的 tableView,并且没有 segue 或任何长这些行的东西。用户可以选择滑动和删除一行,也可以选择其他选项来让一行所代表的用户再次下线。

当用户滑动时,他们可以删除该行。 当用户点击 UIActionsheet 时,会弹出“脱机”(破坏性按钮)或取消选项。

这一切都包装在一个 tableView 委托方法中:

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

    NSLog(@"%d", [indexPath row]);

    Person *person = [people objectAtIndex:indexPath.row];

    UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:@"Need to edit %@'s info?", person.name]
                                                       delegate:self
                                              cancelButtonTitle:@"Cancel"
                                         destructiveButtonTitle:@"Take Offline"
                                              otherButtonTitles:nil, nil];
   [popup showInView:tableView];
   [popup addButtonWithTitle:@"Cancel"];


     [people removeObjectAtIndex:[indexPath row]];
    [tableView reloadData];

我通常会使用 UIActionSheetDelegate 方法来检测按钮的点击。

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 

    if (buttonIndex == 1) 
        NSLog(@"Button 1 was clicked");
    


我遇到的问题是,当我点击表格中的一行时,对象会从数组中删除,表格会立即重新加载。

我不希望在单击“脱机”按钮之前发生这种情况,但我不知道如何做到这一点。我已经尝试过未来,例如将对象存储在实例变量中并从其他方法访问它们,并尝试从 tableView 方法中执行代码,但一直让自己感到困惑。

最好的方法是什么?

亲切的问候

【问题讨论】:

【参考方案1】:

我写了一篇关于如何(以及为什么)将块回调添加到警报视图、操作表和动画的博客文章:

http://blog.innovattic.com/uikitblocks/

使用这种方法,您不必使用委托,而是可以像这样重写您的 tableView:didSelectRowAtIndexPath: 方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    NSLog(@"%d", [indexPath row]);

    Person *person = [people objectAtIndex:indexPath.row];

    UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:@"Need to edit %@'s info?", person.name]
                                              cancelButtonTitle:@"Cancel"
                                         destructiveButtonTitle:@"Take Offline"
                                              otherButtonTitles:nil, nil];

    [popup setHandler:^(UIActionSheet *sheet, NSInteger buttonIndex) 
        [people removeObjectAtIndex:[indexPath row]];
        [tableView reloadData];
     forButtonAtIndex:[popup destructiveButtonIndex]];

    [popup showInView:tableView];

您可以从 GitHub 下载源文件:

https://github.com/Innovattic/UIKit-Blocks

【讨论】:

您好,此代码对我不起作用。我在块开始行没有看到 UIActionSheet 的可见界面。弹出实例也显示错误,直到我在 initWithTitle 之后添加 delegate:nil 您需要为将这个功能添加到您的项目的类别添加源文件。正如我的回答中提到的,您可以从 GitHub 下载它:github.com/Innovattic/UIKit-Blocks 之后,不要忘记将 #include "UIActionSheet+IABlocks.h" 添加到您的视图控制器中。【参考方案2】:

嗯,你说你尝试过的方法是正确的。

您需要在属性中保留对选定Person 的引用。像这样声明一个属性:

@property (nonatomic, strong) Person *selectedPerson;

并将所选人员存储在您的 didSelectRow... 方法中的此属性中。然后,使用 UIActionSheetDelegate 方法来确定用户单击了哪个按钮。如果他们单击“脱机”,则从 people 数组中删除您存储在 selectedPerson 属性中的人。

【讨论】:

完美运行。为什么我宣布坚强?什么时候最终销毁?我只是想澄清一下。 酷。没问题 - 当你声明一个 strong 属性时,这意味着你正在保持对该对象的强引用,即使你是最后一个保持对它的引用的东西,它也会被保留而不是被释放。 那么 ARC 还会负责解除分配吗? 是的,ARC 仍然会为您处理这些问题(当没有指向该对象的强指针时)。

以上是关于如何检测在表视图委托方法中调用的 UIActionSheet 按钮的点击?的主要内容,如果未能解决你的问题,请参考以下文章

如何手动更改 UIMenu 中选定的 UIAction?

如何从视图控制器调用所有方法和函数到应用程序委托?

如何委托telerik网格视图常用方法从每个子页面的父页面调用?

如何在加速时从我的视图控制器外包视图更改操作?

如何在 XIB 中调用 UITextField 的委托方法?

从委托类调用视图控制器方法,有问题