satish
satish

Reputation: 1255

How to disable button in UIActionSheet?

I need to disable the buttons in UIActionSheet. after some operations i need to enable them again. So is there a way to do this.

Thanks

Upvotes: 10

Views: 13747

Answers (6)

Hakim
Hakim

Reputation: 1314

Swift 3.0 version:

let actionSheet = UIAlertController(title:nil, message:nil, preferredStyle:UIAlertControllerStyle.actionSheet)


actionSheet.addAction(UIAlertAction(title:"Modify", style:UIAlertActionStyle.default, handler:{ action in
    // Do your thing here
}))

let disabledDelete = UIAlertAction(title:"Cannot delete this item", style:UIAlertActionStyle.destructive, handler:nil)
disabledDelete.isEnabled = false
actionSheet.addAction(disabledDelete)

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

self.present(actionSheet, animated:true, completion:nil)

Upvotes: 3

Petar
Petar

Reputation: 2283

The provided solutions do not work on iOS 8. In case anyone is not using the UIAlertController for this (which is Apple's recommended way of doing it) this is how I modified @Reuven's answer to work for iOS 8 too:

(the second phase is based on this so answer)

- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled {

    SEL selector = NSSelectorFromString(@"_alertController");

    //iOS 8
    if ([self respondsToSelector:selector]) {

        UIAlertController *alertController = [self valueForKey:@"_alertController"];

        if ([alertController isKindOfClass:[UIAlertController class]]){

            UIAlertAction *action = alertController.actions[buttonIndex];

            [action setEnabled:enabled];

        }

    //iOS 7
    }else{

        for (UIView* view in self.subviews){

            if ([view isMemberOfClass:NSClassFromString(@"UIAlertButton")]) {

                if (buttonIndex == 0) {

                    if ([view respondsToSelector:@selector(setEnabled:)]){

                        UIButton* button = (UIButton*)view;

                        button.enabled = enabled;

                    }

                }

                buttonIndex--;

            }

        }

    }

}

Upvotes: 1

tiritea
tiritea

Reputation: 1279

Slightly improved version of Reuven's [alas I cant add a comment to his 'cause I dont have the 'reputation' yet...].

@interface UIActionSheet (ButtonEnabled)
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled;
@end

@implementation UIActionSheet (ButtonEnabled)
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled
{
    for (UIView* view in self.subviews) {
        if ([view isKindOfClass:[UIButton class]]) {
            if (index-- == 0) {
                [(UIButton*)view setEnabled:enabled];
                break;
            }
        }
    }
}
@end

The previous respondsToSelector: check was extraneous, because we are already checking for UIButton (which is a UIControl subclass, which all support setEnabled]. In keeping with Apple's NSArrays, I also changed to "AtIndex" and NSUInteger, but that's mostly cosmetic.

The overall approach seems to work fine, but please note it does assume the order of the button subviews precisely matches the order of the button indexes when the action sheet was constructed, which isn't strictly documented anywhere AFAIK.

Upvotes: 2

Reuven
Reuven

Reputation: 2132

Based on a number of thread, i've aggregated an answer into a category on UIActionSheet, adding a setButton:toState method as follows. Hope it helps:

@interface UIActionSheet(ButtonState)
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enbaled;
@end

@implementation UIActionSheet(ButtonState)
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled {
    for (UIView* view in self.subviews)
    {
        if ([view isKindOfClass:[UIButton class]])
        {
            if (buttonIndex == 0) {
                if ([view respondsToSelector:@selector(setEnabled:)])
                {
                    UIButton* button = (UIButton*)view;
                    button.enabled = enabled;
                }
            }
            buttonIndex--;
        }
    }
}
@end

Upvotes: 17

mrapplehead
mrapplehead

Reputation: 56

This is probably a bit late. But, the way I figured out is create UIButton(s) and add them to UIActionSheet subview. Make certain these buttons are placed on top and completely cover the default UIActionSheet button(s) to replace. When the UIButton is placed over the default UIActionSheet button, its UIResponder takes precedence over UIActionSheet button UIResponder. So, doing so you can disable and enable those buttons however you'd like anywhere in you UIViewController logic. This may be an alternative to accessing private methods to the SDK (like above - UIThreePartButton) and apple might reject your app. I believe this follows the Apple guidelines.

i.e.

// Instantiate once
if (self.actionSheet==nil)  {
    UIActionSheet *as = [[UIActionSheet alloc] 
                         initWithTitle:@""
                         delegate:self 
                         cancelButtonTitle:@"Cancel"
                         destructiveButtonTitle:@"Load Data"
                         otherButtonTitles:@"Update Data",nil];

    //[actionSheet showInView:self.view];
    self.loadUIButton.frame = CGRectMake(24.0f,25.0f,275.f,46.0f);
    [as addSubview: self.loadUIButton];
    self.updateUIButton.frame = CGRectMake(24.0f,78.0f,275.f,46.0f);
    [as addSubview: self.updateUIButton];
    //[actionSheet addSubview: self.cancelUIButton];
    //[as showFromToolbar: self.navigationController.toolbar];
    self.actionSheet = as;
    [as release];
}
[self.actionSheet showFromToolbar: self.navigationController.toolbar];

Upvotes: 0

oxigen
oxigen

Reputation: 6263

Thees buttons are subviews of UIActionSheet and their class is UIThreePartButton

You can get them and do all that you want:

UIActionSheet *a = [[UIActionSheet alloc]initWithTitle:@"" delegate: nil cancelButtonTitle: @"c" destructiveButtonTitle: @"d" otherButtonTitles: @"ot", nil];
    [a showInView: window];

    for(UIView *v in [a subviews])
    {
        if([[v description] hasPrefix: @"<UIThreePartButton"] )
        {
            v.hidden = YES;  //hide
           //((UIButton*)v).enabled = NO;   // disable

        }
    }

Upvotes: -2

Related Questions