【问题标题】:Set gradient color on custom UIView boarder在自定义 UIView 边框上设置渐变颜色
【发布时间】:2018-12-10 11:25:57
【问题描述】:

我有一个 UIView,其中包含一个 2 UILabels,里面有一个按钮,我想在它的边框上添加一个渐变色。我设法添加了它,并且按钮最终移到了自定义 UIView 之外,而自定义 UIView 在较小的设备上也一直向外缩小。添加gradient color时如何修复UIView以保持相同大小

这里是最初的UIView,前面有两个UILabels和一个带有正常边框颜色的按钮

这里是应用渐变色后的样子

这是我如何应用渐变的代码。

@IBOutlet weak var customView: UIView!

let gradient = CAGradientLayer()
        gradient.frame.size = self.customView.frame.size
        gradient.colors = [UIColor.green.cgColor, UIColor.yellow.cgColor, UIColor.red.cgColor]
        gradient.startPoint = CGPoint(x: 0.1, y: 0.78)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.78)
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = UIBezierPath(rect:   self.customView.bounds).cgPath
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = UIColor.black.cgColor
        shapeLayer.lineWidth = 4
        gradient.mask = shapeLayer
        self.customView.layer.addSublayer(gradient)

【问题讨论】:

  • 也显示自动布局约束...
  • 限制条件很多。不知道如何在这里列出所有这些?
  • for startpoint 和 Endpoint 你可以使用视图中的值而不是使用固定值
  • @Ruban4Axis 以及我是如何做到的。两个点都包含 X 和 Y 位置,包括起点和终点?

标签: ios swift gradient calayer cagradientlayer


【解决方案1】:

当视图调整大小时图层不会调整大小,因此您要创建自定义视图并覆盖layoutSubviews()

这是一个例子:

@IBDesignable
class GradBorderView: UIView {

    var gradient = CAGradientLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    func commonInit() -> Void {
        layer.addSublayer(gradient)
    }
    
    override func layoutSubviews() {
        
        gradient.frame = bounds
        gradient.colors = [UIColor.green.cgColor, UIColor.yellow.cgColor, UIColor.red.cgColor]
        gradient.startPoint = CGPoint(x: 0.1, y: 0.78)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.78)
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = UIBezierPath(rect: bounds).cgPath
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = UIColor.black.cgColor
        shapeLayer.lineWidth = 4
        gradient.mask = shapeLayer
        
    }
    
}

现在,当您的视图根据约束和自动布局更改大小时,您的渐变边框将正确“自动调整大小”。

此外,通过使用@IBDesignable,您可以在 Storyboard / Interface Builder 中布置视图时看到结果。

这是将Grad Border View 宽度设置为240 时的样子:

并将Grad Border View 宽度设置为320


编辑

如果我们想使用圆角,我们可以将shape层路径设置为圆角矩形贝塞尔路径,然后也设置视图层的圆角半径。

例如:

override func layoutSubviews() {

    let cRadius: CGFloat = 8.0
    let bWidth: CGFloat = 4.0
    
    // layer border is centered on layer edge
    let half: CGFloat = bWidth * 0.5
    // make gradient frame size of view + half the border width
    gradient.frame = bounds.insetBy(dx: -half, dy: -half)
    gradient.colors = [UIColor.green.cgColor, UIColor.yellow.cgColor, UIColor.red.cgColor]
    gradient.startPoint = CGPoint(x: 0.1, y: 0.78)
    gradient.endPoint = CGPoint(x: 1.0, y: 0.78)
    
    let shapeLayer = CAShapeLayer()
    // make shapeLayer path the size of view OFFSET by half the border width
    //  with rounded corners
    shapeLayer.path = UIBezierPath(roundedRect: bounds.offsetBy(dx: half, dy: half), cornerRadius: cRadius).cgPath
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.lineWidth = bWidth
    gradient.mask = shapeLayer
    
    // same corner radius as shapeLayer path
    layer.cornerRadius = cRadius
}

【讨论】:

  • 效果很好!有没有办法自动圆角?我的 UIView 的角是圆角的,但它会在渐变上产生奇怪的效果。
  • @XimenaFloresdelaTijera - 请参阅我的回答中的 Edit
  • 这太棒了!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2015-11-29
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多