iPad 崩溃并从子视图控制器显示 UIActionSheet

Posted

技术标签:

【中文标题】iPad 崩溃并从子视图控制器显示 UIActionSheet【英文标题】:iPad crash with UIActionSheet displayed from child view controller 【发布时间】:2011-12-06 17:39:43 【问题描述】:

如果有人问过这个问题,我深表歉意,但我似乎无法在任何地方找到它。我什至在演示项目中重新创建了我的问题,以防你们中的任何人想亲眼目睹,尽管我不知道应该在哪里发布。

我有一个基于 xibless UINavigationController 的应用程序。我的一些子 ViewController 在顶部右侧有一个按钮,然后显示 UIActionSheet。我的应用是为 iPhone 和 iPad 设计的,所以当我准备好显示 UIActionSheet 时,我会这样做:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:@"%@ Menu", [self title]] delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Email", @"Print", nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleDefault];
if ([actionSheet respondsToSelector:@selector(showFromBarButtonItem:animated:)])
    [actionSheet showFromBarButtonItem:[[self navigationItem] rightBarButtonItem] animated:YES];
else [actionSheet showInView:[self view]];
[actionSheet release];

在 iPad 上,我试图显示附加到右栏按钮的 UIActionSheet,而在 iPhone 上,它应该从底部滑入。所有这些都非常有效。

很遗憾,如果您在 iPad 上点击按钮并显示菜单,然后点击应用左上角的后退按钮,菜单不会关闭。取而代之的是 UINavigationController 尽职尽责地弹回 UIActionSheet 仍然存在。如果您尝试点击菜单上的某些内容,您当然会崩溃。如果用户点击屏幕上的任何其他内容而不是“返回”按钮,则菜单会正确关闭。

如果您在 iPhone 上尝试此测试,一切都会按预期进行。没有问题。

我的演示项目有一个 AppDelegate 和一个 ViewController,仅此而已。 AppDelegate 构建了一个 NSDictionary 的 NSDictionary,这样我就有了一个可以递归的模型来演示这个问题。 ViewController 显示了字典的所有键,如果对应的值是 NSDictionary,您可以点击它向下钻取。

【问题讨论】:

【参考方案1】:

这是一个有趣的问题。这是UIActionSheet Class Reference 必须说的话。

在 iPad 上,此方法在弹出窗口中显示操作表并添加 拥有弹出框传递列表按钮的工具栏 意见。因此,工具栏中的点击会导致 相应的工具栏项被调用。如果你想让弹出窗口 当点击不同的工具栏项时被关闭,您必须 在您的操作处理程序方法中实现该行为。

因此,当您显示操作表时,它会自动创建一个 UIPopoverController 并将包含的工具栏(或导航栏)设置为弹出框的直通视图,从而允许触摸事件继续进行。我认为最好的办法是为您的操作表创建一个实例变量,如果它在 -viewWillDisappear: 中可见,则强制它关闭。

- (void)viewWillDisappear:(BOOL)animated

    [super viewWillDisappear:animated];

    if (self.actionSheet.window) // If action sheet is on screen, window is non-nil
        [self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:animated];

【讨论】:

赢家,赢家,吃鸡!我也学到了一些东西。我不知道只有当视图在屏幕上时才会填充窗口属性。非常感谢。 非常感谢,马克。你拯救了我的一天。几个小时以来,我一直在为类似的问题苦苦挣扎。你应该喝啤酒。【参考方案2】:

您是否尝试过在 viewWillDisappear 上强制关闭 ActionSheet?

试试这个:

// In MyViewController.m

    - (void)viewWillDisappear:(BOOL)animated 

        [actionSheet dismissWithClickedButtonIndex:nil animated:animated];

    

*崩溃听起来像是可能的 EXC_BAD_ACCESS。当您因发布而更改视图时,您可能会丢失对“actionSheet”的指针引用。在 .h 文件中保留对 actionSheet 的引用并管理发布时间可能会很好。

*另请参阅文档以获取有关关闭消息的信息:http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html

【讨论】:

以上是关于iPad 崩溃并从子视图控制器显示 UIActionSheet的主要内容,如果未能解决你的问题,请参考以下文章

使用协议应用程序崩溃 ipad

模态视图控制器关闭时应用程序崩溃

在 UIAlertView 上显示 UIActionSheet

UIButton Clicked for Webview 加载到 ipad 后应用程序崩溃

从子视图控制器调用函数不起作用

从子视图控制器呈现主视图控制器