I've noticed that in iOS 7 a **UIActionSheet** automatically dismisses
when a user taps anywhere on the screen on an **iPhone**
. This was NOT the case in iOS 6 and is leading to unintended effects. Is this a UI change? Bug? Is there a way to disable this?
From iOS 7 docs:
"As described in iOS human interface
guidelines, you should include a Cancel button with action sheets
displayed on iPhone and with those displayed on iPad over an open
popover. Otherwise on iPad, action sheets are displayed within a
popover, and the user can cancel the action sheet by tapping outside
the popover, in which case you do not need to include a Cancel
button."
This seems to suggest that the behavior of dismissing when tapping anywhere outside the action sheet should only pertain to iPads. But this is now happening on an iPhone running iOS 7 when it doesn't on an iPhone running iOS 6
Regarding your question Is this a UI change? Bug?
It is seems like an UI change not a bug
how can I say that ?
Have a look at the image i took from iOS7 simulator
It is a image of Maps application of iPhone.
![](https://www.manongdao.com/static/images/pcload.jpg)
When you click on button ( display in red rectangle ) one action sheet will display which have Cancel button
like below
![](https://www.manongdao.com/static/images/pcload.jpg)
And if you click any where else it will close, same behaviour also found in other Apple applications also like safari.
Regarding your question Is there a way to disable this?
Sorry but i don't have answer for that.
A word before I post my solution. It is very easy to fear a minor change in behavior and to want to disable it right away. But consider first consistency. This is how action sheets behave across the operating system. If you disable this behavior, you will break consistency and this will result in a subpar experience for your users.
That said, here is my solution.
UIActionSheet
on iPhone opens its view in a separate UIWindow
instance which becomes key when it is shown. You can access this window using [UIApplication sharedApplication].keyWindow
. If you inspect the view hierarchy of this window, you will notice several private classes such as dimming view. You can recursively traverse this view hierarchy and set view.userInteractionEnabled = NO;
to every view there that is not a subclass of UIButton
. This should do the trick.
As @nvrtdfrst implies in his comments, setting cancelButton: nil
will get rid of the default dismissal behavior. But you can still have a cancel button by setting the text for one of the custom buttons to @"Cancel"
--to be treated by the delegate method, something like this:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:@"Cancel"]) {
// your cancellation code here
}
}
A bit hacky, but that's a simple solution.
H/T: null.
Use
- (void)actionSheet:(UIActionSheet *)actionSheet
didDismissWithButtonIndex:(NSInteger)buttonIndex {...}
This worked for me.
(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[self performSegueWithIdentifier:@"firstOption" sender:self];
}else if (buttonIndex == 1){
[self performSegueWithIdentifier:@"secondOption" sender:self];
} else if (buttonIndex != 0 || buttonIndex != 1) {
[actionSheet cancelButtonIndex];
}
}