突出显示时更改UIButton borderColor与标题同步

时间:2018-09-17 14:12:40

标签: ios swift uibutton uicontrol

我有一个带有边框的自定义 UIButton 。当按钮对用户事件做出反应时,我希望layer.borderColortitleLabel同步-即变为 Highlighted Selected

有时这些事件会延迟播放动画,有时会立即播放。

例如: 点击并按住按钮-立即 释放按钮-带有动画

如何使按钮的边框复制相同的行为?如何跟踪 UIControlStates 之间的过渡?

即是否为边界设置动画取决于过渡: Normal-> Highlighted-无动画 Highlighted-> Normal-带有动画

我如何检测到这种转变?

以下是按钮的代码,该代码无法解决将手指移出范围的事件,但效果很好:

import UIKit

final class BorderButton: UIButton {
  override var isEnabled: Bool {
    didSet {
      updateBorderColor()
    }
  }

  override var isSelected: Bool {
    didSet {
      updateBorderColor(animated: false)
    }
  }

  override var isHighlighted: Bool {
    didSet {
      let animated = !isHighlighted
      updateBorderColor(animated: animated)
    }
  }

  override func tintColorDidChange() {
    super.tintColorDidChange()
    updateBorderColor()
  }

  private func updateBorderColor(animated: Bool = false) {
    var color: UIColor = tintColor
    if !isEnabled || tintAdjustmentMode == .dimmed {
      color = dimmedTintColor()
    } else if isHighlighted {
      color = lightColor()
    }

    if animated {
      let current = layer.borderColor ?? UIColor.clear.cgColor
      let cgColor = color.cgColor
      borderColorAnimation(from: current, to: cgColor, duration: 0.4)
    } else {
      layer.borderColor = color.cgColor
    }
  }


  private func borderColorAnimation(from: CGColor, to: CGColor, duration: CFTimeInterval) {
    let animation = CABasicAnimation(keyPath: "borderColor")
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.fromValue = from
    animation.toValue = to
    animation.duration = duration
    layer.add(animation, forKey: "borderColor")
    layer.borderColor = to
  }

  private func lightColor() -> UIColor {
    var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0
    tintColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
    return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha * 0.2)
  }

  private func dimmedTintColor() -> UIColor {
    var hue: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0
    tintColor.getHue(&hue, saturation: nil, brightness: &brightness, alpha: &alpha)
    return UIColor(hue: hue, saturation: 0, brightness: brightness, alpha: alpha)
  }
}

0 个答案:

没有答案