Search code examples
ioswarningsuiactionsheet

Ios UIActionSheet gives warning while dismissing


I'm using a UIActionSHeet to select from multiple sharing options (facebook, twitter, mail)

But after I select the option I get this warning

 Warning: Attempt to dismiss from view controller <UINavigationController: 0x1ed7eaf0> while a presentation or dismiss is in progress 

This is the code I use :

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    //BOOL displayedNativeDialog;
    SLComposeViewController * tw =  [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    //TWTweetComposeViewController * tw = [[TWTweetComposeViewController alloc]init];
    tw.completionHandler = ^(TWTweetComposeViewControllerResult result)
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    };

    SLComposeViewController * fb = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    fb.completionHandler = ^(SLComposeViewControllerResult result)
    {
        [self dismissViewControllerAnimated:YES completion:nil];
    };

    MFMailComposeViewController * mail = [[MFMailComposeViewController alloc]init];
    [mail setMailComposeDelegate:self];
    [mail.navigationBar setBackgroundColor:[UIColor blackColor]];
    NSData * imageData = [NSData dataWithData:UIImagePNGRepresentation(previewImageView.image)];
    switch (buttonIndex) {
        case 0:
            UIImageWriteToSavedPhotosAlbum(previewImageView.image, nil, nil, nil);
            break;
        case 1:
            [fb addImage:previewImageView.image];
            [self presentViewController:fb animated:YES completion:nil];
            fb = nil;       
            break;
        case 2:
            [actionSheet dismissWithClickedButtonIndex:-1 animated:YES];
            [tw addImage:previewImageView.image];
            [self presentViewController:tw animated:YES completion:nil];
            break;
        case 3:
            [mail addAttachmentData:imageData mimeType:@"image/png" fileName:@"Image.png"];
            [self presentViewController:mail animated:YES completion:nil];
            break;

        default:
            break;
    }
}

I also tried using the delegate function :

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

But I got the same warning.


Solution

  • 1) You should have ivars keeping strong references to these:

    SLComposeViewController * tw    
    SLComposeViewController * fb    
    MFMailComposeViewController * mail
    

    Its bad form to create these then just let ARC recycle them - why not create just the one(s) you need depending on the selected option? You can create objects in case statements with:

    case 1:
    {
        NSObject *obj = ....
        ....
    }   break;
    

    2) You don't need to dismiss the actionSheet - the button click will do it.

    3) Don't present the view controller in the actionSheet delegate call, post a block to the main queue to do it:

    dispatch_async(dispatch_get_main_queue(), ^ {
        [self presentViewController:tw animated:YES completion:nil];
    } );
    

    This is sort of like putting that line in a method, then doing a performSelectorOnMainThread: