在我的应用程序的某些时候,我有一个突出显示的UIButton(例如当用户有他的手指在按钮上),我需要改变背景颜色,而按钮是突出显示的(所以当用户的手指仍然在按钮上)。

我尝试了以下方法:

_button.backgroundColor = [UIColor redColor];

但这并不奏效。颜色保持不变。当按钮没有高亮显示时,我尝试了同一段代码,它工作得很好。我还尝试在改变颜色后调用-setNeedsDisplay,它没有任何效果。

如何强制按钮改变背景颜色?


当前回答

下面是Swift中的一种方法,使用UIButton扩展来添加IBInspectable,称为highlightedBackgroundColor。类似于子类化,但不需要子类。

private var HighlightedBackgroundColorKey = 0
private var NormalBackgroundColorKey = 0

extension UIButton {

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &HighlightedBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &HighlightedBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    private var normalBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &NormalBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &NormalBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    override public var backgroundColor: UIColor? {
        didSet {
            if !highlighted {
                normalBackgroundColor = backgroundColor
            }
        }
    }

    override public var highlighted: Bool {
        didSet {
            if let highlightedBackgroundColor = self.highlightedBackgroundColor {
                if highlighted {
                    backgroundColor = highlightedBackgroundColor
                } else {
                    backgroundColor = normalBackgroundColor
                }
            }
        }
    }
}

我希望这能有所帮助。

其他回答

不确定这是否解决了你所追求的问题,或者是否符合你的总体开发环境,但我想尝试的第一件事是改变触地事件按钮的背景颜色。

选项1:

你需要捕捉两个事件,当用户按下按钮时UIControlEventTouchDown。UIControlEventTouchUpInside和UIControlEventTouchUpOutside将用于当它们释放按钮以返回正常状态时

UIButton *myButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setFrame:CGRectMake(10.0f, 10.0f, 100.0f, 20.f)];
[myButton setBackgroundColor:[UIColor blueColor]];
[myButton setTitle:@"click me:" forState:UIControlStateNormal];
[myButton setTitle:@"changed" forState:UIControlStateHighlighted];
[myButton addTarget:self action:@selector(buttonHighlight:) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(buttonNormal:) forControlEvents:UIControlEventTouchUpInside];

选项2:

返回你想要的高亮颜色的图像。这也可以是一个类别。

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

然后更改按钮的高亮显示状态:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];

下面的uiimage扩展将生成具有指定颜色参数的图像对象。

extension UIImage {
    static func imageWithColor(tintColor: UIColor) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        tintColor.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
       }
    }

按钮的示例用法可以应用于按钮对象,如下所示:

setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 232/255, green: 130/255, blue: 121/255, alpha: 1.0)), for: UIControlState.highlighted)

setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 255/255, green: 194/255, blue: 190/255, alpha: 1.0)), for: UIControlState.normal)

如果你有一张图片,试试这个:

-(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;

或者看看showsTouchWhenHighlighted是否足够。

一个更紧凑的解决方案(基于@aleksejs-mjaliks的答案):

Swift +四分之三的:

override var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? .lightGray : .white
    }
}

斯威夫特2:

override var highlighted: Bool {
    didSet {
        backgroundColor = highlighted ? UIColor.lightGrayColor() : UIColor.whiteColor()
    }
}

如果你不想覆盖,这是一个更新版本的@timur-bernikowich的答案(Swift 4.2):

extension UIButton {
  func setBackgroundColor(_ color: UIColor, forState controlState: UIControl.State) {
    let colorImage = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { _ in
      color.setFill()
      UIBezierPath(rect: CGRect(x: 0, y: 0, width: 1, height: 1)).fill()
    }
    setBackgroundImage(colorImage, for: controlState)
  }
}

试试这个!!!!

TouchedDown事件设置一种颜色,TouchUpInside设置另一种颜色。

- (IBAction)touchedDown:(id)sender {
    NSLog(@"Touched Down");
    btn1.backgroundColor=[UIColor redColor];
}

- (IBAction)touchUpInside:(id)sender {
    NSLog(@"TouchUpInside");
    btn1.backgroundColor=[UIColor whiteColor];    
}