Search code examples
iosobjective-cdelegatesuiactionsheet

Unable to present a subview while in UIActionSheetDelegate method


I have the following code which (supposedly) presents a subview when triggered by an action sheet button:

- (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{    
    if (buttonIndex ==0) {
        [self.view addSubview:self.customView];
        //
        // heavy lifting of method here
        //
        // self.customView removes itself from superview before actionSheet:dismissWithButtonIndex: finishes
    }
}

After doing all the 'heavy lifting' the subview removes itself from the view heirachy (before the completion of the action sheet delegate method).

Alas!! I'm finding that the subview never gets shown on screen. Indeed, if I stop the added subview from dismissing itself and set breakpoints, I find that it is DOES get displayed, but only AFTER the UIActionSheet delegate method is completed.

Initially, I thought this was because the subview was being presented in the actionSheet:clickedButtonAtIndex: UIActionSheet delegate method - causing the action sheet to block the presentation of the view.

Looking at other methods available, actionSheet:didDismissWithButtonIndex: seemed like it might solve my problems as This method is invoked after the animation ends and the view is hidden (per Apple Docs). Still no luck!

Any thoughts of how I might present this subview before the method is completed.


Solution

  • It seems like you're adding and removing the subview in the same method (actionSheet:didDismissButtonIndex:). This means that the operation is done in the same cycle of the main run loop. Note that view rendering is done only at the end of the operation and this means that the "addSubview" is overridden by the "removeFromSuperview" thus leading to the view don't being rendered at all.

    What you can do is to "addSubview" in the delegate method that is called before the action sheet is dismissed but after the button has been clicked, and then call "removeFromSuperview" in the delegate method called after the action sheet has been dismissed:

    
    -(void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex {
        [self.view addSubview:self.subviewToAdd];
        self.subviewToAdd.center=CGPointMake(160,100);
    }
    
    -(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
        [self.subviewToAdd removeFromSuperview];
    }
    

    In this example you will see your view just flashing as the add/removal operation is limited in the action sheet dismissal animation time. You can set it to remove after a longer time by changing the actionSheet:didDismissWithButtonIndex: in this way, adding a small delay:

    -(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
        [self.subviewToAdd performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.0];
        //[self.subviewToAdd removeFromSuperview];
    }