UIActionSheet crash in iOS8beta

2019-02-14 16:57发布

问题:

I have code which simply display UIActionSheet on button click. but it will crash when I build it using XCode5.1 + iOS8beta in iPad.

below is a code I used to display UIActionSheet.

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

Note:
- It perfectly work with XCode6beta + iOS8beta (iPhone/iPad both)
- It perfectly work with XCode5.1 + iOS8beta (iPhone only)

Log while exception is came is as below.

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



Question :
1] Why my application is crash ?
2] Is it iOS8beta bug ?


Patch till apple fix this issue
Create Objective-C categor for UIActionSheet class

CODE :

#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];
    }
}

Reference link

回答1:

I also had the same problem. i used ShowFromBarButtonItem function instead of ShowInView Function.

[organizeActionSheet showFromBarButtonItem:btnAction animated:NO];

if use ShowFromRect or showFromBarButtonItem runtime exception will not come. i think it is a bug of IOS8 Beta, when i use ShowInView Runtime exception is coming.

This bug is not happening in IOS Beta 4..

I do get some warning messages in the debug window when built using Xcode 5.1, but the action sheet does appear. In iOS 8 beta 4, it appears as a small pop-up window outside of the view (at the side), whereas in iOS 7, it used to appear as buttons that slid up from the bottom of the view.



回答2:

I am having the same issue, and this is still 'broken' in beta 5. In my case though I am just getting a dimmed screen without action sheet instead of a crash.

Except showing an action sheet directly in a view on iPad is not a good design anyway. You should use popover containing an action sheet and pointing to the button or UI element that spawned the choice as Sabareesh suggested. Alerts are for messages that are disconnected from any UI elements, action sheets are always associated with an onscreen UI element as far as I know.



回答3:

I've seen the same problem for a while with showInView not working from IOS 8 Beta 2 through Beta 5. I just submitted bug report:17971746.



回答4:

I also get a crash on iOS8 final on iPad.

This is my simple workaround:
replace
[actionSheet showFromBarButtonItem:myButton animated:YES];
by
[actionSheet showFromRect:myButton.navBarView.frame inView:self.view animated:YES];



回答5:

according to this https://developer.apple.com/library/ios/documentation/Uikit/reference/UIActionSheet_Class/index.html Answer is from here: How to do "actionSheet showFromRect" in iOS 8?