How do you change UIButton image alpha on disabled state?

44,185

Solution 1

If setting alpha while the button is disabled doesn't work, then just make your disabled image at the alpha value you desire.

Just tested this, you can set the alpha on the UIButton, regardless of state and it works just fine.

self.yourButton.alpha = 0.25;

Solution 2

Credit goes to @bryanmac for his helpful answer. I used his code as a starting point, but found the same thing can be achieved without using a UIImageView.

Here's my solution:

- (UIImage *)translucentImageFromImage:(UIImage *)image withAlpha:(CGFloat)alpha
{
    CGRect rect = CGRectZero;
    rect.size = image.size;

    UIGraphicsBeginImageContext(image.size);
    [image drawInRect:rect blendMode:kCGBlendModeScreen alpha:alpha];
    UIImage * translucentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return translucentImage;
}

Set the button's background image for disabled state:

UIImage * disabledBgImage = [self translucentImageFromImage:originalBgImage withAlpha:0.5f];
[button setBackgroundImage:disabledBgImage forState:UIControlStateDisabled];

EDIT:

I refined my solution further by creating a category on UIImage with this method:

- (UIImage *)translucentImageWithAlpha:(CGFloat)alpha
{
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
    [self drawInRect:bounds blendMode:kCGBlendModeScreen alpha:alpha];

    UIImage * translucentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return translucentImage;
}

Set the button's background image for disabled state:

UIImage * disabledBgImage = [originalBgImage translucentImageWithAlpha:0.5f];
[button setBackgroundImage:disabledBgImage forState:UIControlStateDisabled];

Solution 3

You need two instances of UIImage, one for enabled and one for disabled.

The tough part is for the disabled one, you can't set alpha on UIImage. You need to set it on UIImageView but button doesn't take an UIImageView, it takes a UIImage.

If you really want to do this, you can load the same image into the disabled button state after creating a resultant image from the UIImageView that has the alpha set on it.

UIImageView *uiv = [UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png"];

// get resultant UIImage from UIImageView
UIGraphicsBeginImageContext(uiv.image.size);
CGRect rect = CGRectMake(0, 0, uiv.image.size.width, uiv.image.size.height);
[uiv.image drawInRect:rect blendMode:kCGBlendModeScreen alpha:0.2];  

UIImage *disabledArrow = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext();

[button setImage:disabledArrow forState:UIControlStateDisabled];

That's a lot to go through to get an alpha controlled button image. There might be an easier way but that's all I could find. Hope that helps.

Solution 4

Subclassing UIButton and extending the setEnabled: method seems to work:

- (void) setEnabled:(BOOL)enabled {    
    [super setEnabled:enabled];
    if (enabled) {
        self.imageView.alpha = 1;
    } else {
        self.imageView.alpha = .25;
    }
}

I haven't tested it thoroughly, but did find the value resets if the screen is rotated. Adding the same code to the setFrame: method fixes that, but I'm not sure if there are other situations where this value is changed.

Solution 5

In case anyone needs it, here's an answer in Swift:

Subclass UIButton and override enabled

class MyCustomButton: UIButton {

override var enabled: Bool {
    didSet{
        alpha = enabled ? 1.0 : 0.3
    }
}

Set the class of any button you want to have this property to "MyCustomButton" (or whatever you choose to name it)

 @IBOutlet weak var nextButton: MyCustomButton!
Share:
44,185
Deamon
Author by

Deamon

Your friendly neighbor ios/web developer!

Updated on May 16, 2020

Comments

  • Deamon
    Deamon about 4 years

    I have a UIButton with an image and on its disabled state, this image should have .3 alpha.

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    UIImage *arrowImage = [UIImage imageNamed:@"arrow.png"];
    [button setImage:arrowImage forState:UIControlStateNormal];
    
    // The arrow should be half transparent here
    [button setImage:arrowImage forState:UIControlStateDisabled];
    

    How do I accomplish this?

    UPDATE: I noticed, by default UIButton does reduce the alpha of the image on disabled state (probably at .5?). But I'd like to know how to fine-tune this value.