简体   繁体   English

如何在禁用状态下更改 UIButton 图像 alpha?

[英]How do you change UIButton image alpha on disabled state?

I have a UIButton with an image and on its disabled state, this image should have .3 alpha.我有一个带有图像的 UIButton,在它的禁用状态下,这个图像应该有 0.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?).更新:我注意到,默认情况下 UIButton 确实会降低禁用状态下图像的 alpha(可能为 0.5?)。 But I'd like to know how to fine-tune this value.但我想知道如何微调这个值。

If setting alpha while the button is disabled doesn't work, then just make your disabled image at the alpha value you desire.如果在按钮禁用时设置 alpha 不起作用,那么只需将禁用的图像设置为您想要的 alpha 值。

Just tested this, you can set the alpha on the UIButton, regardless of state and it works just fine.刚刚对此进行了测试,您可以在 UIButton 上设置 alpha,无论状态如何,它都可以正常工作。

self.yourButton.alpha = 0.25;

Credit goes to @bryanmac for his helpful answer .感谢@bryanmac有用回答 I used his code as a starting point, but found the same thing can be achieved without using a UIImageView .我使用他的代码作为起点,但发现不使用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上创建一个类别来进一步完善我的解决方案:

- (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.您需要两个UIImage实例,一个用于启用,一个用于禁用。

The tough part is for the disabled one, you can't set alpha on UIImage .困难的部分是禁用的,你不能在UIImage上设置 alpha 。 You need to set it on UIImageView but button doesn't take an UIImageView , it takes a UIImage .您需要在UIImageView上设置它,但按钮不采用UIImageView ,它采用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.如果你真的想这样做,你可以在从设置了 alpha 的UIImageView创建结果图像后,将相同的图像加载到禁用按钮状态。

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.要获得 alpha 控制的按钮图像,需要做很多工作。 There might be an easier way but that's all I could find.可能有更简单的方法,但这就是我能找到的。 Hope that helps.希望有帮助。

Subclassing UIButton and extending the setEnabled: method seems to work:子类化 UIButton 并扩展setEnabled:方法似乎有效:

- (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.将相同的代码添加到setFrame:方法可以解决这个问题,但我不确定是否还有其他情况会更改此值。

In case anyone needs it, here's an answer in Swift:如果有人需要它,这里有一个 Swift 的答案:

Subclass UIButton and override enabled子类 UIButton 和覆盖启用

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)将您想要拥有此属性的任何按钮的类设置为“MyCustomButton”(或您选择的任何名称)

 @IBOutlet weak var nextButton: MyCustomButton!

I found that none of these solutions really work.我发现这些解决方案都没有真正奏效。 The cleanest way of doing it is to subclass, and instead of using self.imageView, just add your own custom imageView like this:最简洁的方法是子类化,而不是使用 self.imageView,只需添加您自己的自定义 imageView,如下所示:

_customImageView = [[UIImageview alloc] initWithImage:image];

Then add your custom alpha like so:然后像这样添加您的自定义 alpha:

- (void)setEnabled:(BOOL)enabled {
    [super setEnabled:enabled];
    if (enabled) {
        _customImageView.alpha = 1.0f;
    } else {
        _customImageView.alpha = 0.25f;
    }
}

Swift 3 :斯威夫特3

extension UIImage {
    func copy(alpha: CGFloat) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        draw(at: CGPoint.zero, blendMode: .normal, alpha: alpha)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}

Usage:用法:

button.setImage(image.copy(alpha: 0.3), for: .disabled)

The button's image view.按钮的图像视图。 (read-only) (只读)

@property(nonatomic, readonly, retain) UIImageView *imageView

Although this property is read-only, its own properties are read/write.虽然这个属性是只读的,但它自己的属性是读/写的。

- (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;使用: [btnRegister setBackgroundImage:[self imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled]; btnRegister.enabled = false; [btnRegister setBackgroundImage:[self imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled]; btnRegister.enabled = false;

A swift 4 version of Steph Sharp's answer: Steph Sharp 答案的 swift 4 版本:

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)
}

Swift 5:斯威夫特 5:

Here's a solution that extends the UIButton class.这是一个扩展 UIButton 类的解决方案。 No need to sub-class.不需要子类。 In my example, button alpha is set to 0.55 if .isEnabled is false, and 1.0 if it's true.在我的示例中,如果 .isEnabled 为 false,则按钮 alpha 设置为 0.55,如果为 true,则设置为 1.0。

extension UIButton {扩展 UIButton {

override open var isEnabled: Bool{
    didSet {
        self.alpha = isEnabled ? 1.0 : 0.55
    }
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM