我想实现这样的目标。我已经搜索过了。我得到的建议是我可以在按钮后面放置一个渐变 View ,其高度和宽度比按钮大。但我想要精确的角半径和带有渐变的边框颜色。
最佳答案
您可以创建自己的 BorderedButton
子类,它将:
- 添加渐变子层;
- 创建由边框路径组成的形状图层;和
- 使用该形状层作为渐变层的 mask ,以在路径形状中产生渐变边界。
例如:
@IBDesignable
class BorderedButton: UIButton {
@IBInspectable var lineWidth: CGFloat = 3 { didSet { setNeedsLayout() } }
@IBInspectable var cornerRadius: CGFloat = 10 { didSet { setNeedsLayout() } }
let borderLayer: CAGradientLayer = {
let borderLayer = CAGradientLayer()
borderLayer.type = .axial
borderLayer.colors = [#colorLiteral(red: 0.6135130525, green: 0.3031745553, blue: 0.9506058097, alpha: 1).cgColor, #colorLiteral(red: 0.9306473136, green: 0.1160953864, blue: 0.8244602084, alpha: 1).cgColor]
borderLayer.startPoint = CGPoint(x: 0, y: 1)
borderLayer.endPoint = CGPoint(x: 1, y: 0)
return borderLayer
}()
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
override func layoutSubviews() {
super.layoutSubviews()
borderLayer.frame = bounds
let mask = CAShapeLayer()
let rect = bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)
mask.path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
mask.lineWidth = lineWidth
mask.fillColor = UIColor.clear.cgColor
mask.strokeColor = UIColor.white.cgColor
borderLayer.mask = mask
}
}
private extension BorderedButton {
func configure() {
layer.addSublayer(borderLayer)
}
}
注意:
- 我在
layoutSubviews
方法中更新了渐变层的frame
和用作mask
的路径,这确保了如果尺寸发生变化(例如,您正在使用约束来定义 View 的尺寸),边框会正确呈现。 - 我制作了这个
@IBDesignable
,这样您甚至可以将它添加到 Storyboard 中,并且您会看到它正确呈现。 - 我已经将
cornerRadius
和lineWidth
设置为@IBInspectable
以便您可以在 IB 中调整它们(并且因为它们有didSet
设置“需要布局”的观察者,他们将确保在 Storyboard 中可以观察到变化。
无论如何,这会产生:
关于ios - 如何将渐变边框颜色应用于 UIButton?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58668177/