以编程方式将渐变边框颜色应用于 UIButton
Posted
技术标签:
【中文标题】以编程方式将渐变边框颜色应用于 UIButton【英文标题】:Programmatically applying a gradient border color to a UIButton 【发布时间】:2018-04-17 10:26:37 【问题描述】:我正在尝试创建一个带有渐变颜色的按钮,但我似乎无法让它工作。我的按钮的borderColor 属性没有应用颜色。我尝试实现another SO post 建议的代码,但它不起作用。不知道为什么。有人可以帮我理解为什么吗?
我用来更改按钮布局的代码是:
// Constraints
myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
myButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50).isActive = true
myButton.heightAnchor.constraint(equalToConstant: myButton.height).isActive = true
myButton.widthAnchor.constraint(equalToConstant: myButton.width).isActive = true
// Layout
myButton.backgroundColor = UIColor.black
myButton.tintColor = UIColor.white
myButton.layer.cornerRadius = callButtonHeightAndWidth.height / 2
myButton.layer.borderWidth = 10
myButton.setTitle("Test", for: .normal)
myButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Regular", size: 27)
我尝试使用我称为setGradientBorderWidthColor
的函数扩展 UIView,代码如下所示:
func setGradientBorderWidthColor(button: UIButton)
let gradientColor = CAGradientLayer()
gradientColor.frame = CGRect(origin: CGPoint.zero, size: button.frame.size)
gradientColor.colors = [UIColor.red.cgColor, UIColor.blue.cgColor, UIColor.green.cgColor]
let shape = CAShapeLayer()
shape.lineWidth = 3
shape.path = UIBezierPath(rect: button.bounds).cgPath
shape.strokeColor = UIColor.black.cgColor
shape.fillColor = UIColor.clear.cgColor
gradientColor.mask = shape
button.layer.addSublayer(gradientColor)
我还尝试将上面相同的代码放在我的 ViewController 中的 viewDidLoad
function 中,但这也不起作用。有什么建议吗?
编辑 1:
使用代码和提供的建议我最终得到了这个。问题是,每当我向按钮添加角半径时,边缘都会被切断。
【问题讨论】:
您可以删除 myButton 的高度和宽度锚点。 这有什么帮助? 没有工作意味着你得到了错误的输出或什么?请试着解释一下。 @ViniApp 根本没有输出。运行代码时没有任何反应。 我的意思是高度和宽度锚点没有附加值,您可以将其从代码中删除。这确实是一个离题的评论:) 【参考方案1】:您可以按照以下代码制作渐变边框:
func makeButton()
let buttonView = UIButton()
self.view.addSubview(buttonView)
buttonView.translatesAutoresizingMaskIntoConstraints = false
buttonView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: self.view.safeAreaInsets.top + 30).isActive = true
buttonView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 40).isActive = true
buttonView.widthAnchor.constraint(equalToConstant: 120
).isActive = true
buttonView.heightAnchor.constraint(equalToConstant: 50).isActive = true
self.view.layoutIfNeeded()
let outerPath = UIBezierPath()
outerPath.move(to: CGPoint.init(x: buttonView.bounds.minX - 5, y: buttonView.bounds.minY - 5))
outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.maxX + 5, y: buttonView.bounds.minY - 5))
outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.maxX + 5, y: buttonView.bounds.maxY + 5))
outerPath.addLine(to: CGPoint.init(x: buttonView.bounds.minX - 5, y: buttonView.bounds.maxY + 5))
outerPath.close()
let path = UIBezierPath()
path.move(to: CGPoint.init(x: buttonView.bounds.minX + 5, y: buttonView.bounds.minY + 5))
path.addLine(to: CGPoint.init(x: buttonView.bounds.maxX, y: buttonView.bounds.minY + 5))
path.addLine(to: CGPoint.init(x: buttonView.bounds.maxX, y: buttonView.bounds.maxY))
path.addLine(to: CGPoint.init(x: buttonView.bounds.minX + 5, y: buttonView.bounds.maxY))
path.close()
outerPath.append(path)
let maskLayer = CAShapeLayer()
maskLayer.fillRule = kCAFillRuleEvenOdd
maskLayer.path = outerPath.cgPath
maskLayer.fillColor = UIColor.red.cgColor
buttonView.layer.addSublayer(maskLayer)
self.view.layoutIfNeeded()
let gradient = CAGradientLayer()
gradient.frame = self.view.frame
gradient.colors = [UIColor.blue.cgColor,
UIColor.red.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 1)
gradient.endPoint = CGPoint(x: 1, y: 0)
gradient.mask = maskLayer
buttonView.layer.addSublayer(gradient)
buttonView.setTitle("Hello World", for: .normal)
基本上,您必须创建一个 shapeLayer,创建两条路径并将 fillRule 设置为 kcaFillModeEvenOdd,然后对这个蒙版应用渐变。你有它:
【讨论】:
嗨,@SWAT!谢谢您的答复。您将如何使用您的示例制作圆角甚至圆形按钮?【参考方案2】:只需从您的代码中删除两行代码即可正常运行。
myButton.layer.borderWidth = 10
myButton.layer.cornerRadius = 10
代码将如下所示:
myButton.backgroundColor = UIColor.clear
myButton.frame = CGRect(x: 100, y: 100, width: 150, height: 40)
myButton.tintColor = UIColor.black
myButton.setTitle("Test", for: .normal)
myButton.titleLabel?.font = UIFont(name: "HelveticaNeue-
Regular", size: 27)
setGradientBorderWidthColor(button: myButton)
self.view.addSubview(myButton)
用这个函数替换你的 setGradientBorderWidthColor 函数
func setGradientBorderWidthColor(button: UIButton)
let gradientColor = CAGradientLayer()
gradientColor.frame = CGRect(origin: CGPoint.zero, size: button.frame.size)
gradientColor.colors = [UIColor.blue.cgColor, UIColor.green.cgColor]
let pathWithRadius = UIBezierPath(roundedRect:button.bounds, byRoundingCorners:[.topRight, .topLeft, .bottomLeft , .bottomRight], cornerRadii: CGSize(width: 20.0, height: 20.0))
let shape = CAShapeLayer()
shape.lineWidth = 3
shape.path = pathWithRadius.cgPath
shape.strokeColor = UIColor.black.cgColor
shape.fillColor = UIColor.clear.cgColor
gradientColor.mask = shape
button.layer.mask = shape
button.layer.addSublayer(gradientColor)
输出:
GradientBorderWidthColor
【讨论】:
好的,所以这部分工作。如果我添加一个圆角半径,则 eges 将被切断。我已编辑我的帖子以包含此图像。 @Araine,现在检查编辑答案,希望现在这对你有用。! @Araine,如果对您批准答案有帮助的话。 嗨@nishee,感谢您的帮助!我对角落的渲染方式有疑问。如果要制作圆形按钮,则将圆形的0、90、180和270度切掉。我不知道为什么。 @Araine,你想要制作圆形按钮。?如果是,你能告诉我按钮的 x y 和高度宽度吗以上是关于以编程方式将渐变边框颜色应用于 UIButton的主要内容,如果未能解决你的问题,请参考以下文章
两个 UIButton 形成一个具有渐变颜色,另一个具有边框和圆角