I have a UIButton with an image and on its disabled state, this image should have .3 alpha.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIIm
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];
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.
A swift 4 version of Steph Sharp's answer:
extension UIImage {
func translucentImageWithAlpha(alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0)
let bounds = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.draw(in: bounds, blendMode: .screen, alpha: alpha)
let translucentImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return translucentImage!
}
}
Which you can use like this:
if let image = self.image(for: .normal) {
self.setImage(image.translucentImageWithAlpha(alpha: 0.3), for: .disabled)
}
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.
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!
- (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image; }
Use: [btnRegister setBackgroundImage:[self imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled];
btnRegister.enabled = false;