How to make a uiactionsheet dismiss when you tap outside eg above it?
Asked Answered
C

11

12

How do i make a uiactionsheet dismiss when you tap outside eg above it? This is for iPhone. Apparently the ipad does this by default (I may be wrong).

Caryopsis answered 30/5, 2011 at 4:12 Comment(0)
C
15

Ok got a solution. The following applies to a subclass of a UIActionSheet

// For detecting taps outside of the alert view
-(void)tapOut:(UIGestureRecognizer *)gestureRecognizer {
    CGPoint p = [gestureRecognizer locationInView:self];
    if (p.y < 0) { // They tapped outside
        [self dismissWithClickedButtonIndex:0 animated:YES];
    }
}

-(void) showFromTabBar:(UITabBar *)view {
    [super showFromTabBar:view];

    // Capture taps outside the bounds of this alert view
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOut:)];
    tap.cancelsTouchesInView = NO; // So that legit taps on the table bubble up to the tableview
    [self.superview addGestureRecognizer:tap];
    [tap release];
}

The gist of it is to add a gesture recogniser to the action sheet's superview, and test all taps to see if they are above the action sheet.

Caryopsis answered 30/5, 2011 at 5:33 Comment(2)
I am currently attempting this solution, however I am finding that the UIAlertView soaks up all events, so the tapOut: method is never called by the gesture recognizer. Hence, this solution doesn't work at all.Dolabriform
I am getting the same results as @StCredZero. In 8.1 if you are using a UIAlertController, adding a UIAlertActionStyleCancel it will give you that effect. In previous version, there is no way to add this feature.Accessory
R
4

it may be useful to you Use:

- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated

previous so question

Ruelle answered 30/5, 2011 at 4:26 Comment(4)
That's fine for dismissing it, but i'd still need some way of capturing when the 'tapped outside' event occurred, so i could call this function.Caryopsis
developer.apple.com/library/ios/#documentation/uikit/reference/…Ruelle
I'm trying with the tap gesture recogniser, but i can't find which view to attach it to. The actionsheet's view? Its superview? The tabbar passed to it in 'showfromtabbar' ? Its superview? None of them work...Caryopsis
Got it working. Thanks for the tip about the gesture recogniser.Caryopsis
P
3

I think you are looking for this method

- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated

EDIT

you can use this on your action sheet object and it works just fine but you cannot register event outside that sheet like the grayed out part

may be if you use UITapGestureRecognizer on your view controller than it might do the trick.

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(nothing)];
[actionSheet addGestureRecognizer:recognizer];
Painkiller answered 30/5, 2011 at 4:35 Comment(3)
Again, this is what i'd call once i've got a handler that is called whenever the user taps outside. But capturing the 'tapped outside' event is my problem here. ThanksCaryopsis
Doesn't work either by adding the GR to the action sheet or the container view.Foxed
Well then you haven't tried it yet, cause in my case it worked.Painkiller
G
1

After setting the cancelButtonIndex property of UIActionSheet with a valid value, tapping outside will dismiss the UIActionSheet. I have tried in iOS 9. However, if this cancelButtonIndex is not set of set to a wrong value (e.g. an index beyond the total button count in the UIActionSheet), nothing will happen when tapping outside.

Garnishee answered 26/4, 2016 at 2:20 Comment(0)
D
1

No need of any tap gesture. Simply use UIAlertActionStyleCancel action.

Discordant answered 12/4, 2017 at 5:22 Comment(0)
A
0

You can't do that by tapping outside because action sheet covers whole view some transparent black view with buttons in form of sheet in iphones but in ipad this behavior presents by default .

so for touching outside you cant call touch methods. so i don't think so you can do in this way and also when apple provide a cancel button in action sheet then why not you do use that button rather than this.

Atonsah answered 30/5, 2011 at 5:0 Comment(2)
We've got a customised action sheet which has a table presenting many options, covering the normal buttons, which is why i'm trying to do this.Caryopsis
then why not you are trying for touches methods touchesBegain.Atonsah
P
0

This does not answer the question exactly, but here is what I do to close the picker when clicking on one of its items (this prevents from adding additional "done" button or "outside click" stuff):

Implement the viewForRow picker's delegate method in which you create a UILabel and return it:

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view

On those custom row labels, add a tap action handler:

UITapGestureRecognizer *tapAction = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleClick:)];
[label addGestureRecognizer:tapAction];

In the handleClick callback, dismiss the open sheet (the one that contains the picker view):

[pickerSheet dismissWithClickedButtonIndex:0 animated:TRUE];
Peeress answered 29/11, 2012 at 17:18 Comment(0)
P
0

Use showFromRect, for example:

UIView *barButtonView = [barButtonItem valueForKey:@"view"];
CGRect buttonRect = barButtonView.frame;

[actionSheet showFromRect:buttonRect inView:self.view animated:YES];
Pinkeye answered 14/7, 2014 at 20:9 Comment(0)
H
0

in iOS7 I add dismissWithClickedButtonIndex msg in gestureRecognizerShouldBegin, and it works.

Hardner answered 4/8, 2014 at 15:51 Comment(0)
C
-1

Use .cancel UIAlertActionStyle as an option.

Chromatology answered 7/7, 2017 at 2:14 Comment(0)
E
-1

Just add an alert with style: .cancel. Rest of the work will be done automatically.

alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

Ecumenicism answered 4/7, 2021 at 11:37 Comment(1)
The same solution has alerady been proposed in the answers above. If you want to improve an existing answer by adding a code snippet to it, you can do so by editing it. Avoid posting duplicate answers.Microcircuit

© 2022 - 2024 — McMap. All rights reserved.