【问题标题】:How do you change UIButton image alpha on disabled state?如何在禁用状态下更改 UIButton 图像 alpha?
【发布时间】:2011-11-24 11:17:33
【问题描述】:

我有一个带有图像的 UIButton,在它的禁用状态下,这个图像应该有 .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];

我该如何做到这一点?

更新:我注意到,默认情况下 UIButton 在禁用状态下会降低图像的 alpha(可能为 0.5?)。但我想知道如何微调这个值。

【问题讨论】:

标签: ios iphone objective-c uibutton uiimage


【解决方案1】:

如果在禁用按钮时设置 alpha 不起作用,那么只需将禁用的图像设置为所需的 alpha 值。

刚刚测试过了,你可以在 UIButton 上设置 alpha,不管状态如何,效果都很好。

self.yourButton.alpha = 0.25;

【讨论】:

  • 问题是准备好的图像不知道它后面会是什么视图(这是alpha的点)
  • 我同意这是 alpha 的重点,PNG 支持 alpha,那么现在使用带有 alpha 的股票图像有什么问题?我一直这样做,事实上我唯一不使用它的时候是我想在运行时动态更改 alpha 以获得淡入淡出效果。
  • 关于 alpha PNG 的要点。同样对于 [button setAlpha],我看到了它并且它有效,唯一的问题是您或其他代码不能简单地设置按钮的状态 - 您始终必须记住设置 alpha 并在状态更改时重置 alpha。
【解决方案2】:

感谢 @bryanmachelpful answer。我以他的代码为起点,但发现不使用UIImageView 也可以实现相同的目标。

这是我的解决方案:

- (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;
}

将按钮的背景图片设置为禁用状态:

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

编辑:

我通过使用这种方法在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;
}

将按钮的背景图片设置为禁用状态:

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

【讨论】:

  • 这很好用。但是它没有使用我的图像的@2x 版本。如果你使用 UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);而不是 UIGraphicsBeginImageContext(image.size) 它也将支持视网膜图像。
  • @JonHobson 感谢您的提示!
  • 这是一个很好的答案!我现在在我的应用程序中使用它。谢谢@StephSharp!
【解决方案3】:

您需要两个UIImage 实例,一个用于启用,一个用于禁用。

困难的部分是残疾人,你不能在UIImage上设置alpha。您需要将其设置为UIImageView,但按钮不需要UIImageView,它需要UIImage

如果您真的想这样做,您可以在从 UIImageView 创建一个已设置 alpha 的结果图像后,将相同的图像加载到禁用按钮状态。

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];

要获得一个 Alpha 控制的按钮图像,需要做很多工作。可能有更简单的方法,但这就是我能找到的全部。希望对您有所帮助。

【讨论】:

    【解决方案4】:

    子类化 UIButton 并扩展 setEnabled: 方法似乎可行:

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

    我没有彻底测试过,但确实发现如果屏幕旋转,值会重置。将相同的代码添加到 setFrame: 方法可以解决此问题,但我不确定是否还有其他情况会更改此值。

    【讨论】:

    • 我发现有时这不起作用。我认为 UIButton 在做自己的事情时会修改imageView(可能会在默认的选定图像之间更改?),如果在点击按钮时调用setEnabled(例如,调用@ 987654326@,同时 UIButton 在选定/突出显示/默认状态之间修改其外观)。
    • 然后覆盖'layoutSubviews'并在需要时调用'[self setNeedsLayout]'。
    • -(void)setEnabled:(BOOL)enabled { super.enabled = enabled; self.imageView.alpha = enabled ? 1 : 0.5; self.titleLabel.alpha = self.imageView.alpha; }
    【解决方案5】:

    如果有人需要,这里有一个 Swift 的答案:

    子类 UIButton 并启用覆盖

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

    将您希望拥有此属性的任何按钮的类设置为“MyCustomButton”(或您选择的任何名称)

     @IBOutlet weak var nextButton: MyCustomButton!
    

    【讨论】:

      【解决方案6】:

      我发现这些解决方案都没有真正奏效。最简洁的方法是子类化,而不是使用 self.imageView,只需像这样添加您自己的自定义 imageView:

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

      然后像这样添加您的自定义 alpha:

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

      【讨论】:

        【解决方案7】:

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

        用法:

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

        【讨论】:

          【解决方案8】:

          按钮的图像视图。 (只读)

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

          虽然这个属性是只读的,但它自己的属性是读/写的。

          【讨论】:

            【解决方案9】:

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

            你可以这样使用:

            if let image = self.image(for: .normal) {
                self.setImage(image.translucentImageWithAlpha(alpha: 0.3), for: .disabled)
            }
            

            【讨论】:

              【解决方案10】:
              - (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; }
              

              使用:[btnRegister setBackgroundImage:[self imageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled]; btnRegister.enabled = false;

              【讨论】:

              • 这是一个代码转储,没有任何有用的评论尝试。请改进这一点。
              【解决方案11】:

              斯威夫特 5:

              这是一个扩展 UIButton 类的解决方案。不需要子类。在我的示例中,如果 .isEnabled 为 false,则按钮 alpha 设置为 0.55,如果为 true,则设置为 1.0。

              扩展 UIButton {

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

              }

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-01-23
                • 2014-08-28
                • 2015-03-26
                • 2017-04-22
                • 2013-01-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多