【问题标题】:Disabled UIButton not faded or grey禁用的 UIButton 不褪色或变灰
【发布时间】:2011-08-08 13:49:37
【问题描述】:

在我的 iPhone 应用程序中,我有一个在 Interface Builder 中创建的 UIButton。我可以在我的代码中像这样成功地启用和禁用它...

sendButton.enabled = YES;

sendButton.enabled = NO;

但是,按钮的视觉外观始终相同!它不会褪色或变灰。如果我尝试单击它,它会按预期启用或禁用。我错过了什么吗?它不应该看起来褪色或变灰吗?

【问题讨论】:

  • 你在 UIButton 中使用图像吗?
  • 不,它没有,你需要设置它的 alpha,因此它会起作用。

标签: ios iphone cocoa-touch uibutton


【解决方案1】:

您可以使用以下代码:

sendButton.enabled = YES;
sendButton.alpha = 1.0;

or

sendButton.enabled = NO;
sendButton.alpha = 0.5;

【讨论】:

  • 虽然这可行,但我认为根据控制状态改变外观的解决方案,如下面的 thisthis 是一个更好的主意。他们使用内置机制来实现自动更改,而不是需要根据其状态显式更新控件的外观。
【解决方案2】:

只需更改状态配置以禁用并选择您想要的,禁用状态的背景图像

【讨论】:

  • 这只会更改 Button 子标题中的属性。背景颜色位于 View 子标题下,因此不会被状态配置更改。
  • 这不适用于视图的背景颜色。在我的项目中,我结合了之前的答案和这个。
【解决方案3】:

另一个选项是更改禁用状态的文本颜色(例如浅灰色)。

在故事板编辑器中,从State Config 弹出按钮中选择Disabled。使用Text Color 弹出按钮更改文本颜色。

在代码中,使用-setTitleColor:forState: 消息。

【讨论】:

  • 这似乎是一个比调整 alpha 的例外答案更好的解决方案。几个月前我已经投票了,现在我回到这里遇到同样的问题,我希望我能再做一次!
  • 是的,似乎是一个可行的解决方案。我只是使用浅灰色。
【解决方案4】:

要使按钮在禁用时变淡,您可以为其设置 alpha。有两种选择:

第一种方式:如果你想申请你应用中的所有按钮,那么你可以像这样为 UIButton 写extension

extension UIButton {

    open override var isEnabled: Bool{
        didSet {
            alpha = isEnabled ? 1.0 : 0.5
        }
    }

}

第二种方式:如果你只是想在你的应用中申请一些按钮,那么你可以像下面这样从 UIButton 编写一个自定义类,并使用你想申请的这个类: p>

class MyButton: UIButton {
    override var isEnabled: Bool {
        didSet {
            alpha = isEnabled ? 1.0 : 0.5
        }
    }
}

【讨论】:

    【解决方案5】:

    尝试为UIControlStateDisabled(禁用灰色图像)和UIControlStateNormal(普通图像)设置不同的图像,以便按钮为您生成禁用状态。

    【讨论】:

    • 他没有使用图像——但您可以将同样的概念应用于[ UIButton setAttributedTitle:forState:]。创建属性字符串,将文本前景色设置为透明色。
    【解决方案6】:

    如果使用文本按钮,可以放入viewDidLoad实例方法

    - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state
    

    示例:

    [self.syncImagesButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
    

    【讨论】:

    • 这应该是文本按钮的可接受答案。当前接受的答案适用于图像按钮。我从 op 的 cmets 得到的是他有一个文本按钮..
    【解决方案7】:

    您可以使用adjustsImageWhenDisabled,这是UIButton的属性
    (@property (nonatomic) BOOL adjustsImageWhenDisabled)

    例如:

     Button.adjustsImageWhenDisabled = false
    

    【讨论】:

    • 这是做什么的?你能解释一下他为什么要使用它吗?
    【解决方案8】:

    Swift 4+

    
    extension UIButton {
        override open var isEnabled: Bool {
            didSet {
                if self.isEnabled {
                    self.alpha = 1.0
                }
                else {
                    self.alpha = 0.5
                }
                //make sure button is updated
                self.layoutIfNeeded()
            }
        }
    }
    

    如何使用

    myButton.isEnabled = false
    
    

    【讨论】:

    • 这里为什么需要 DispatchQueue? isEnabled 本身难道不是一个仅主线程的操作吗?
    【解决方案9】:

    这是一个相当古老的问题,但有一种非常简单的方法可以实现。

    myButton.userInteractionEnabled = false

    这只会禁用任何触摸手势而不改变按钮的外观

    【讨论】:

    • 我认为 OP 有相反的问题。他们已经在改变这个标志,但想要改变外观。
    【解决方案10】:

    为不同的状态设置title color

    @IBOutlet weak var loginButton: UIButton! {
            didSet {
                loginButton.setTitleColor(UIColor.init(white: 1, alpha: 0.3), for: .disabled)
                loginButton.setTitleColor(UIColor.init(white: 1, alpha: 1), for: .normal)
            }
        }
    

    用法:(文字颜色会自动改变)

    loginButton.isEnabled = false
    

    【讨论】:

      【解决方案11】:

      Swift 中:

      previousCustomButton.enabled = false
      previousCustomButton.alpha = 0.5
      

      nextCustomButton.enabled = true
      nextCustomButton.alpha = 1.0
      

      【讨论】:

        【解决方案12】:

        在 Swift > 3.0 中创建扩展,而不是单独创建每个按钮

        extension UIButton {
            override open var isEnabled : Bool {
                willSet{
                    if newValue == false {
                        self.setTitleColor(UIColor.gray, for: UIControlState.disabled)
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案13】:

          您可以使用第一个答案,这将是一个更好的结果。

          在属性检查器中(当您选择按钮时),将 State Config 更改为 Disabled 以设置在禁用时将出现的新图像(删除 Content->Enabled 检查中的标记以进行它禁用)。

          当您将状态更改为启用时,图像将从该状态加载。

          为此添加 alpha 逻辑是一个很好的细节。

          【讨论】:

            【解决方案14】:

            我遇到了同样的问题。设置 alpha 不是我想要的。

            UIButton 具有“背景图片”和“背景颜色”。 对于图像,UIButton 的属性为

            @property (nonatomic) BOOL adjustsImageWhenDisabled

            当按钮被禁用时,背景图像会变浅。 对于背景颜色,设置 alpha,Ravin 的解决方案,效果很好。

            首先,您必须检查您是否未选中实用程序-属性下的“禁用调整图像”框。
            然后,检查此按钮的背景颜色。

            (希望对您有所帮助。这是一篇旧帖子;Xcode 中的内容可能已经改变)。

            【讨论】:

              【解决方案15】:

              如果UIButton处于selecteddisabled的组合状态,则其状态为UIControlStateSelected | UIControlStateDisabled

              所以它的状态需要这样调整:

              [button setTitleColor:color UIControlStateSelected | UIControlStateDisabled];
              [button setImage:image forState:UIControlStateSelected | UIControlStateDisabled];
              

              一种方法是对UIButton 进行子类化,如下所示:

              @implementation TTButton
              - (void)awakeFromNib {
                 [super awakeFromNib];
              
                  //! Fix behavior when `disabled && selected`
                  //! Load settings in `xib` or `storyboard`, and apply it again.
                  UIColor *color = [self titleColorForState:UIControlStateDisabled];
                  [self setTitleColor:color forState:UIControlStateDisabled];
              
                  UIImage *img = [self imageForState:UIControlStateDisabled];
                  [self setImage:img forState:UIControlStateDisabled];
              }
              
              - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
                  [super setTitleColor:color forState:state];
              
                  //
                  if (UIControlStateDisabled == state) {
                      [super setTitleColor:color forState:UIControlStateSelected | state];
                      [super setTitleColor:color forState:UIControlStateHighlighted | state];
                  }
              }
              
              - (void)setImage:(UIImage *)image forState:(UIControlState)state {
                  [super setImage:image forState:state];
              
                  if (UIControlStateDisabled == state) {
                      [super setImage:image forState:UIControlStateSelected | state];
                      [super setImage:image forState:UIControlStateHighlighted | state];
                  }
              }
              
              @end
              

              【讨论】:

              • 这应该是公认的答案。在 Swift 上,你需要类似 setTitleColor(disabledColor, for: [.disabled, .selected])
              【解决方案16】:

              这个问题有很多答案,但如果你真的想使用 backgroundColor 来设置按钮的样式,它们看起来都不是很有用。 UIButton 有很好的选项来为不同的控件状态设置不同的图像,但背景颜色没有相同的功能。 因此,一种解决方案是添加扩展程序,该扩展程序将从颜色生成图像并将它们应用于按钮。

              extension UIButton {
                private func image(withColor color: UIColor) -> UIImage? {
                  let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
                  UIGraphicsBeginImageContext(rect.size)
                  let context = UIGraphicsGetCurrentContext()
              
                  context?.setFillColor(color.cgColor)
                  context?.fill(rect)
              
                  let image = UIGraphicsGetImageFromCurrentImageContext()
                  UIGraphicsEndImageContext()
              
                  return image
                }
              
                func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
                  self.setBackgroundImage(image(withColor: color), for: state)
                }
              }
              

              此解决方案只有一个问题 - 此更改不会应用于在情节提要中创建的按钮。对我来说这不是问题,因为我更喜欢从代码中设置 UI 样式。如果您想使用情节提要,则需要使用 @IBInspectable 的一些额外魔法。

              第二个选项是子类化,但我更愿意避免这种情况。

              【讨论】:

                【解决方案17】:

                也许您可以子类化您的按钮并覆盖您的 isEnabled 变量。优点是您可以在多个地方重复使用。

                override var isEnabled: Bool {
                     didSet {
                         if isEnabled {
                             self.alpha = 1
                         } else {
                             self.alpha = 0.2
                         }
                     }
                 }
                

                【讨论】:

                  【解决方案18】:

                  看起来下面的代码可以正常工作。但在某些情况下,这不起作用。

                  sendButton.enabled = NO;
                  sendButton.alpha = 0.5;
                  

                  如果上面的代码不起作用,请将其包装在主线程中。 所以

                  dispatch_async(dispatch_get_main_queue(), ^{
                      sendButton.enabled = NO;
                      sendButton.alpha = 0.5
                  });
                  

                  如果你选择 swift,像这样

                  DispatchQueue.main.async {
                      sendButton.isEnabled = false
                      sendButton.alpha = 0.5
                  }
                  

                  另外,这里我写了UIButton扩展函数。

                  extension UIButton {
                      func enable() {
                          DispatchQueue.main.async {
                              self.isEnabled = true
                              self.alpha = 1.0
                          }
                      }
                  
                      func disable() {
                          DispatchQueue.main.async {
                              self.isEnabled = false
                              self.alpha = 0.5
                          }
                      }
                  }
                  

                  谢谢你,享受编码!!!

                  【讨论】:

                    【解决方案19】:
                    #import "UIButton+My.h"
                    #import <QuartzCore/QuartzCore.h>
                    @implementation UIButton (My)
                    
                    
                    -(void)fade :(BOOL)enable{
                        self.enabled=enable;//
                        self.alpha=enable?1.0:0.5;
                    }
                    
                    @end
                    

                    .h:

                    #import <UIKit/UIKit.h>
                    @interface UIButton (My)
                    
                    -(void)fade :(BOOL)enable;
                    
                    @end
                    

                    【讨论】:

                    • 您的代码附带的一些描述会提供更好的答案。
                    猜你喜欢
                    • 1970-01-01
                    • 2018-12-21
                    • 1970-01-01
                    • 2011-09-12
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-07-09
                    • 1970-01-01
                    • 2014-11-30
                    相关资源
                    最近更新 更多