【问题标题】:UIActionSheet crash in iOS8betaiOS8beta 中的 UIActionSheet 崩溃
【发布时间】:2014-08-13 08:46:29
【问题描述】:

我的代码只是在单击按钮时显示 UIActionSheet。 但是当我在 iPad 中使用 XCode5.1 + iOS8beta 构建它时它会崩溃。

下面是我用来显示 UIActionSheet 的代码。

UIActionSheet *tmpActionSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                                delegate:self
                                                       cancelButtonTitle:@"Cancel"
                                                  destructiveButtonTitle:nil
                                                       otherButtonTitles:
                                     @"Ok",
                                     nil];
    [tmpActionSheet showInView:self.view];

注意:
- 它与 XCode6beta + iOS8beta(iPhone/iPad 两者)完美配合
- 与 XCode5.1 + iOS8beta 完美搭配(仅限 iPhone)

异常发生时的日志如下。

2014-06-23 15:54:04.860 ActionSheetDemo[680:191598] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x14e60ef0 V:|-(0)-[UIView:0x14d419a0]   (Names: '|':UIView:0x14d3a8b0 )>",
    "<NSLayoutConstraint:0x14e60880 _UIDimmingKnockoutBackdropView:0x14d2ca80.top == UIView:0x14d419a0.top>",
    "<NSLayoutConstraint:0x14e61600 V:[_UIDimmingKnockoutBackdropView:0x14d2ca80(>=44)]>",
    "<NSLayoutConstraint:0x14e66240 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14e66240 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-06-23 15:54:04.872 ActionSheetDemo[680:191598] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x14e60ef0 V:|-(0)-[UIView:0x14d419a0]   (Names: '|':UIView:0x14d3a8b0 )>",
    "<NSLayoutConstraint:0x14e60880 _UIDimmingKnockoutBackdropView:0x14d2ca80.top == UIView:0x14d419a0.top>",
    "<NSLayoutConstraint:0x14e61600 V:[_UIDimmingKnockoutBackdropView:0x14d2ca80(>=44)]>",
    "<NSLayoutConstraint:0x14d25f80 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14d25f80 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-06-23 15:54:04.878 ActionSheetDemo[680:191598] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x14e60ef0 V:|-(0)-[UIView:0x14d419a0]   (Names: '|':UIView:0x14d3a8b0 )>",
    "<NSLayoutConstraint:0x14e60880 _UIDimmingKnockoutBackdropView:0x14d2ca80.top == UIView:0x14d419a0.top>",
    "<NSLayoutConstraint:0x14e61600 V:[_UIDimmingKnockoutBackdropView:0x14d2ca80(>=44)]>",
    "<NSLayoutConstraint:0x14e67740 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14e67740 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-06-23 15:54:04.885 ActionSheetDemo[680:191598] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x14e60ef0 V:|-(0)-[UIView:0x14d419a0]   (Names: '|':UIView:0x14d3a8b0 )>",
    "<NSLayoutConstraint:0x14e60880 _UIDimmingKnockoutBackdropView:0x14d2ca80.top == UIView:0x14d419a0.top>",
    "<NSLayoutConstraint:0x14e61600 V:[_UIDimmingKnockoutBackdropView:0x14d2ca80(>=44)]>",
    "<NSLayoutConstraint:0x14d38a30 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14d38a30 _UIDimmingKnockoutBackdropView:0x14d2ca80.bottom ==>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-06-23 15:54:04.892 ActionSheetDemo[680:191598] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <_UIAlertShimPresentingViewController: 0x14d450c0>.'
*** First throw call stack:
(0x24702c2f 0x315cdd1f 0x27ffa6e7 0x27df9799 0x2838f3bd 0x2838e94d 0x6bfdd 0x27d4a6c7 0x27d4a669 0x27d34a4d 0x27d4a099 0x27d49d73 0x27d42ff1 0x27d198b1 0x27f8f13d 0x27d183c1 0x246ca597 0x246c99ab 0x246c8029 0x246145a1 0x246143b3 0x2b8cc1b9 0x27d78c41 0x6c239 0x31b67aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException



问题:
1] 为什么我的应用程序崩溃了?
2] 它是 iOS8beta 错误吗?


补丁直到苹果修复此问题
UIActionSheet 类创建Objective-C categor

代码:

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

@implementation UIActionSheet (simplyShowInViewAddition)

- (void) simplyShowInView:(UIView *) view
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0"))
    {
        [self showInView:view];
    }
    else
    {
        // "Translating" UIActionSheet to UIAlertController for better compatibility with iOS 8
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:self.title preferredStyle:UIAlertControllerStyleActionSheet];
        int nactions = [self numberOfButtons];
        int i=0;
        while(i<nactions)
        {
            NSString *button_title=[self buttonTitleAtIndex:i];
            UIAlertActionStyle style=UIAlertActionStyleDefault;
            if(i==[self cancelButtonIndex])
            {
                style = UIAlertActionStyleCancel;
            }
            else if(i==[self destructiveButtonIndex])
            {
                style = UIAlertActionStyleDestructive;
            }

            UIAlertAction *newAction = [UIAlertAction actionWithTitle:button_title style:style handler:^(UIAlertAction *action) {
                NSLog(@"clicked action %d",i);
                [self.delegate actionSheet:self clickedButtonAtIndex:i];
            }];

            [alert addAction:newAction];
            i++;
        }

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        {
            [alert setModalPresentationStyle:UIModalPresentationPopover];

            UIPopoverPresentationController *popPresenter = [alert
                                                             popoverPresentationController];
            popPresenter.sourceView = view;
            popPresenter.sourceRect = CGRectMake(view.frame.size.width/2-1, 0.45*view.frame.size.height, 2, 1);
            popPresenter.permittedArrowDirections = 0;
        }
        UIViewController *sourceViewController;
        if(self.delegate!=nil && [self.delegate respondsToSelector:@selector(presentViewController:animated:completion:)])
        {
            NSLog(@"presenting UIAlertController on source view controller");
            sourceViewController=(UIViewController *)(self.delegate);
        }
        else
        {
            // When the actionsheet delegate is not a UIViewController
            NSLog(@"presenting UIAlertController on displayed view controller");
            sourceViewController = /* Set up a method here to obtain the view controller where you want to display it */
        }
        [sourceViewController presentViewController:alert animated:YES completion:nil];
    }
}

参考link

【问题讨论】:

  • 这可能与他们将 UIActionSheet 替换为 UIAlertController 的事实有关
  • 我想使用 XCode5.1 构建它,在那种情况下我无法使用 UIAlertController

标签: ipad xcode5 uiactionsheet ios8


【解决方案1】:

我也遇到了同样的问题。我使用 ShowFromBarButtonItem 函数而不是 ShowInView 函数。

[organizeActionSheet showFromBarButtonItem:btnAction animated:NO];

如果使用 ShowFromRect 或 showFromBarButtonItem 不会出现运行时异常。 我认为这是 IOS8 Beta 的一个错误,当我使用 ShowInView 运行时异常即将到来。

IOS Beta 4 中没有此错误。

使用 Xcode 5.1 构建时,我在调试窗口中确实收到了一些警告消息,但操作表确实出现了。在 iOS 8 beta 4 中,它显示为视图外部(侧面)的一个小弹出窗口,而在 iOS 7 中,它曾经显示为从视图底部向上滑动的按钮。

【讨论】:

  • 感谢您解决我的第 2 个问题,我也认为这是 iOS8 测试版错误,但是如果我想从视图中显示操作表,它会自行处理
  • 我遇到了同样的问题。这是 iPad 上 iOS8 beta 2 的新功能。 Beta 1 没有出现同样的问题。
  • 也在 iPad、iOS8b2 上看到它。绝对看起来像是一个操作系统错误。
  • 同样的问题,得到bad access。寻找Zombies 我发现在尝试显示UIActionSheet 时,dealloc 被发送到UINavigationController,在一个具有no Nav Contoroller 的VC 中。此外,这看起来很随机。我需要点击几次才能获得bad access。有时它显示,但在单击按钮时会崩溃。希望这是一个错误,不必为 iOS7/8 使用 if-else。 (Xcode 6 beta 2,iOS 8 模拟器)
  • 在 b3 中似乎仍然被破坏:(
【解决方案2】:

我遇到了同样的问题,这在 beta 5 中仍然“损坏”。在我的情况下,虽然我只是得到一个没有操作表而不是崩溃的变暗屏幕。

除了直接在 iPad 上的视图中显示操作表之外,无论如何都不是一个好的设计。您应该使用包含操作表的弹出框并指向生成选项的按钮或 UI 元素,如 Sabareesh 建议的那样。警报适用于与任何 UI 元素断开连接的消息,据我所知,操作表始终与屏幕上的 UI 元素相关联。

【讨论】:

  • 您可以将符号断点设置为UIViewAlertForUnsatisfiableConstraints,但我不知道如何修复它:)
【解决方案3】:

一段时间以来,我发现 showInView 在 IOS 8 Beta 2 到 Beta 5 中都无法正常工作。我刚刚提交了错误报告:17971746。

【讨论】:

    【解决方案4】:

    我在 iPad 上也遇到了 iOS8 final 崩溃。

    这是我的简单解决方法:
    替换
    [actionSheet showFromBarButtonItem:myButton animated:YES];
    作者
    [actionSheet showFromRect:myButton.navBarView.frame inView:self.view animated:YES];

    【讨论】:

    • navBarView 不是 UIBarButtonItem 的属性,navBarView 在整个 iOS 8 SDK 中都不存在
    【解决方案5】:
    猜你喜欢
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多