UIActionSheet cancel button strange behaviour

24,483

Solution 1

Instead of passing the current view controller's view to the action sheet, use the showFromTabBar: method of UIActionSheet.

The Right Way
This will give the correct tappable area:

[actionSheet showFromTabBar:self.tabBarController.tabBar];

The Wrong Way
This will put the tappable area in the wrong place (if you're using a tab bar or toolbar):

[actionSheet showInView:self.view];

If you're using a toolbar, use the showFromToolbar: method instead. You'll need a reference to the toolbar, most likely an ivar

[actionSheet showFromToolbar:self.myToolbar];

My Old Answer Also works, but is hacky:

Just found a possible answer:

01-Dec-2008 10:22 PM Tom Saxton: I looked at this bug some more, and it seems to be an issue with the tabbar.

If you call UIActionSheet's [sheet showInView:self.view] from a view controller that is a child of a UITabViewController, then the hit testing on the cancel button fails in that portion of the UIActionSheet that lies above the tabbar's view.

If you instead pass in the UITabBarController's view, then the UIActionSheet acts as expected.

NOTE: in iPhone OS 2.1 and earlier, the UIActionSheet came up from the top of the tab bar when you pass the child view, but in 2.2, it comes up from the bottom of the tab bar, and thus covers the tab view.

http://openradar.appspot.com/6410780

Edit: It works correctly when I change the view to be the tab bar's view

[sheet showInView:self.parentViewController.tabBarController.view];

Solution 2

I found an answer over here that works.

using: [filterActionSheet showInView:[self.view window]];

i tried a few ways to get to my tab bar and they way this app is set up it seem convoluted...

Solution 3

Instead use:

[sheet showFromTabBar:theTabBar];

Solution 4

Here is the fix.Try this:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];

Solution 5

I think a combination of three of the answers is the right way of handling this:

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

i.e., use showFromTabBar (that's why it exists) and you don't need the parentViewController as Nathan pointed out (in fact, self.parentViewController.tabBarController.tabBar returns nil for me.

Share:
24,483

Related videos on Youtube

nevan king
Author by

nevan king

Mostly questions and answers about iOS & maps

Updated on July 08, 2022

Comments

  • nevan king
    nevan king almost 2 years

    I have a UIBarButtonItem opening an action sheet to offer users choices about what to do. Everything works as expected unless I try to click on the "Cancel" button. The target of the button appears to have moved up from where it should be. I can only activate it by clicking somewhere in the middle of the "Cancel" and "Ok" buttons.

    I've tried at action sheets in other applications and they work fine, so it's not just my big thumb. The action sheet is opening in a UIViewController

    - (void)showOpenOptions
    {
        UIActionSheet *sheet = [[UIActionSheet alloc] 
        initWithTitle:NSLocalizedString(@"Open link in external application?", @"Open in external application")
        delegate:self
        cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel")
        destructiveButtonTitle:NSLocalizedString(@"Open Link", @"Open Link")
        otherButtonTitles:nil];
    
        [sheet showInView:self.view];
        [sheet release];
    }
    
    • nevan king
      nevan king almost 15 years
      Yeah, I read the human interface guidelines recently and saw that. Changed it from red to grey.
  • bentford
    bentford almost 15 years
    Upvoted this because it works. Why is this better than the other answers?
  • Stephen Darlington
    Stephen Darlington over 14 years
    I corrected this from showInTabBar: to showFromTabBar:. Also note that there's a 'showFromToolbar:` method, depending on what screen furniture you have at the bottom of the screen. This, I think, is a better answer than the accepted answer.
  • Billy Gray
    Billy Gray about 14 years
    Stephen, curious why you think this is better than specifying showInView:theTabBar? From a coupling perspective I'd think that showInView would probably be more ideal, in case later on the tabBar is dropped, maybe replaced with a toolbar, for instance. The particular sub view controller shouldn't really have to know or care, I'd think.
  • William Denniss
    William Denniss about 14 years
    PERFECT! Thanks. This is the correct solution for me, as I was having this issue with a UITableViewController that had a toolbar not a TabBar like others here.
  • Christopher Pickslay
    Christopher Pickslay about 14 years
    If the tab bar is dropped later, you're going to have to edit that line of code regardless (unless perhaps theTabBar is a poorly-named reference to a view that's passed in). So I don't see how this method is any more coupled than showInView:theTabBar. I use showFromTabBar: as well, as it seems safer to me. I don't know what's going on under the covers, but I imagine that showFromTabBar: is less likely to break in future OS releases than showFromView: with a tab bar view.
  • Andy
    Andy over 13 years
    Why the parentViewController? Even if the view is in a navigationview tabBarController should still point to the right place. Works for me without the parentViewController in any case.
  • Kevin
    Kevin over 13 years
    Another answer seems potentially better. Look for [actionSheet showInView:[self.view window]]. Seems more straight forward and more generic.
  • fulvio
    fulvio over 13 years
    Thank you so much for posting this answer.
  • Oscar Gomez
    Oscar Gomez over 12 years
    Thank you works good, although parentViewController is not required.
  • Christian Gossain
    Christian Gossain over 12 years
    good stuff, this worked for me! this is definitely the easiest way to do it!
  • Dominik Seibold
    Dominik Seibold over 12 years
    Of course it returns nil, because the parent view controller (which is the UITabBarViewController) isn't nested itself into another UITabBarController, so its tabBarController-property is nil.
  • Mike Keskinov
    Mike Keskinov over 12 years
    I don't have tab bar in my app, but still have such problem. I solved it with '[serf.view window]'. It is not tab bar problem anyway.
  • Mike Keskinov
    Mike Keskinov about 12 years
    It cause another problem. ActionSheet appears in portrait orientation when device in landscape (as well as all other content).
  • Pradeep Mittal
    Pradeep Mittal over 10 years
    Upvoted but i still have issues with that target area problem.The cancel button now works fine for me though.