ios - 在 .selected 状态下更改自定义 UIButton 的颜色

标签 ios swift uibutton

我为应用的主屏幕设计了一个径向渐变按钮:

    class RadialGradientButton: UIButton {

    var insideColor: UIColor = ColorScheme.limeGreen
    var outsideColor: UIColor = UIColor.white

    var gradientLocation: CGFloat = 0.9

    override func draw(_ rect: CGRect) {
        let colors = [insideColor.cgColor, outsideColor.cgColor] as CFArray
        let center = CGPoint(x: rect.size.width / 2, y: rect.size.height / 2)

        let endRadius = rect.size.width / 2

        let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: [gradientLocation, 1.0])

        UIGraphicsGetCurrentContext()!.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: endRadius, options: .drawsBeforeStartLocation)
    }

    }

现在使用这个按钮我遇到了一个用户体验问题:点击按钮时,由于渐变颜色设置,它的外观不会以任何方式改变。我希望它的行为像任何系统按钮一样 - 也就是说,insideColor 应该在 .selected 状态下变暗。

Touch DownTouch Up Inside 事件被触发时,我尝试使用 setNeedsDisplay(),但是这个方法确实不执行立即重绘,而且可能会影响性能。

也许这里有人可以引导我朝着正确的方向前进。

最佳答案

draw() 方法在首次显示 View 或发生使 View 的可见部分无效的事件时调用。覆盖此方法,UIKit 创建并配置图形上下文以在其上绘制和渲染渐变层。这就是您选择的背景不起作用的原因。

您可以通过在 View 中插入两层来实现此行为 - 一层用于突出显示,另一层用于正常状态。稍后更改触摸事件的行为。

import UIKit
import QuartzCore


class RoundedButton: UIButton {

var gradientBackgroundLayer : CAGradientLayer?
var selectedLayer : CALayer?

var insideColor: UIColor = UIColor.green;
var outsideColor: UIColor = UIColor.white;
var gradientLocation: NSNumber = 0.9;
let kAnimationLength:CGFloat = 0.15;

override init(frame: CGRect) {
    super.init(frame: frame);
    commonInit();
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder);
    commonInit();
}

override func awakeFromNib() {
    super.awakeFromNib();
    commonInit();
}

func commonInit() {
    self.backgroundColor = nil;
    self.clipsToBounds = true;
    self.setTitleColor(UIColor.white, for: UIControlState.normal)

    let colors : [CGColor] = [insideColor.cgColor, outsideColor.cgColor];
    let locations : [NSNumber] = [0,gradientLocation];

    let layer : CAGradientLayer = CAGradientLayer();
    layer.frame = self.bounds;
    layer.colors = colors;
    layer.locations = locations;

    self.gradientBackgroundLayer = layer;

    let selectedLayer : CALayer = CALayer();
    selectedLayer.frame = self.bounds;
    selectedLayer.backgroundColor = UIColor.lightGray.cgColor
    self.selectedLayer = selectedLayer;
}

func performLayout() {
    self.gradientBackgroundLayer?.frame = self.bounds;
    self.selectedLayer?.frame = self.bounds;

    self.layer.insertSublayer(self.gradientBackgroundLayer!, at: 1);
    self.layer.insertSublayer(self.selectedLayer!, at: 0);

    self.layer.cornerRadius = self.frame.size.height / 2.0;
}

override func layoutSubviews() {
    super.layoutSubviews();
    performLayout();
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event);

    UIView.animate(withDuration: TimeInterval(kAnimationLength), delay: 0, options: UIViewAnimationOptions.curveEaseIn, animations: {
        self.isHighlighted = true;
        self.selectedLayer?.isHidden = false;
        self.gradientBackgroundLayer?.isHidden = true;
    }, completion: nil);
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesEnded(touches, with: event);

    UIView.animate(withDuration: TimeInterval(kAnimationLength), delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
        self.isHighlighted = false;
        self.gradientBackgroundLayer?.isHidden = false;
        self.selectedLayer?.isHidden = true;
    }, completion: nil);
}

试试这个。希望它能奏效。

关于ios - 在 .selected 状态下更改自定义 UIButton 的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46761284/

相关文章:

ios - Xcode 不提供崩溃时的调试信息

ios - 在 Controller Init 上分配 viewModel?

iphone - 有没有iPhone sdk的TFTP客户端,可以传文件到TFTP服务器?

ios - iOS 中的图像共享

ios - 接收我们在用户登录时存储的用户默认值(swift3 ...)

ios - DTCoreText 与 Swift 3 问题

ios - 使用计时器功能设置标题时按钮文本闪烁,Swift

ios - 创建一个能够检查按下的按钮的标题的函数

iphone - 检测何时按下自定义 UIButton

ios - UITableView 中可移动但不可编辑的行