如何在 Swift 4 的 UIView 中创建带圆角的渐变边框

Posted

技术标签:

【中文标题】如何在 Swift 4 的 UIView 中创建带圆角的渐变边框【英文标题】:How to create Gradient border with rounded corners at UIView in Swift 4 【发布时间】:2018-07-13 12:35:39 【问题描述】:

我想在 UIView 中设置从左到右渐变的边框颜色 [Red, Green]。 比如:

我尝试了以下代码:-

class View: UIView 

    override func layoutSubviews() 
        super.layoutSubviews()

        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .bottomLeft, .topRight, .bottomRight], cornerRadii: CGSize(width: frame.size.height / 2, height: frame.size.height / 2))

        let gradient = CAGradientLayer()
        gradient.frame =  CGRect(origin: CGPoint.zero, size: frame.size)
        gradient.colors = [UIColor.green.cgColor, UIColor.red.cgColor]

        let shape = CAShapeLayer()
        shape.lineWidth = 10
        shape.path = path.cgPath
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        gradient.mask = shape

        layer.insertSublayer(gradient, at: 0)
    

我无法解决三个问题:- 1- 我已将 lineWidth 设置为 10,但它在角落处显示宽度 10,而在水平/垂直处仅显示 5。2- 我想显示渐变从左到右不是从上到下。

我尝试下面的代码设置从左到右的渐变但不起作用:-

//        gradient.frame =  CGRect(origin: CGPoint.zero, size: frame.size)
        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.5)

请帮忙。提前致谢。

【问题讨论】:

见***.com/a/36836787/7084910 这个我也试过了。 【参考方案1】:

编辑

我想设置从左到右的边框

你需要改变 gradient.startPoint 和 gradient.endPoint

enum Direction 
    case horizontal
    case vertical


class View: UIView 

init(frame: CGRect, cornerRadius: CGFloat, colors: [UIColor], lineWidth: CGFloat = 5, direction: Direction = .horizontal) 
    super.init(frame: frame)

    self.layer.cornerRadius = cornerRadius
    self.layer.masksToBounds = true
    let gradient = CAGradientLayer()
    gradient.frame = CGRect(origin: CGPoint.zero, size: self.frame.size)
    gradient.colors = colors.map( (color) -> CGColor in
        color.cgColor
    )

    switch direction 
    case .horizontal:
        gradient.startPoint = CGPoint(x: 0, y: 1)
        gradient.endPoint = CGPoint(x: 1, y: 1)
    case .vertical:
        gradient.startPoint = CGPoint(x: 0, y: 0)
        gradient.endPoint = CGPoint(x: 0, y: 1)
    

    let shape = CAShapeLayer()
    shape.lineWidth = lineWidth
    shape.path = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, 
    dy: lineWidth), cornerRadius: cornerRadius).cgPath
    shape.strokeColor = UIColor.black.cgColor
    shape.fillColor = UIColor.clear.cgColor
    gradient.mask = shape

    self.layer.addSublayer(gradient)


required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")

如您所见,我添加了一些额外的参数。我通过向 roundedRect 添加插图解决了这个问题:

shape.path = UIBezierPath(roundedRect: self.bounds.insetBy(dx: lineWidth, 
dy: lineWidth), cornerRadius: cornerRadius).cgPath

如何使用:

let myView = View(frame: CGRect(x: 0, y: 0, width: 200, height: 50), cornerRadius: 25, colors: [UIColor.red, .orange, .yellow], lineWidth: 2, direction: .horizontal)
    myView.center = view.center
    view.addSubview(myView)

截图:

roundedViewWithGradient

【讨论】:

谢谢@rmaddy,但是我如何才能从左到右渲染渐变呢?我想从左到右绘制渐变。喜欢i.stack.imgur.com/V01uy.png 我编辑了我的答案,所以你可以选择是垂直渐变还是水平渐变。【参考方案2】:

问题在于贝塞尔路径未在其边界内绘制。它是围绕它的边界绘制的。所以一半的笔划宽度在里面,一半在外面。你需要调整边界来处理这个问题。

将传入贝塞尔路径的框架从 self.bounds 更改为 self.bounds.insetBy(dx: 5, dy: 5),其中 5 是线宽的一半。

还有台词:

gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)

确实导致渐变从左到右。

这是您的完整代码:

class View: UIView 
    override func layoutSubviews() 
        super.layoutSubviews()

        let path = UIBezierPath(roundedRect: self.bounds.insetBy(dx: 5, dy: 5), byRoundingCorners: [.topLeft, .bottomLeft, .topRight, .bottomRight], cornerRadii: CGSize(width: frame.size.height / 2, height: frame.size.height / 2))

        let gradient = CAGradientLayer()
        gradient.frame =  CGRect(origin: CGPoint.zero, size: frame.size)
        gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
        gradient.colors = [UIColor.green.cgColor, UIColor.red.cgColor]

        let shape = CAShapeLayer()
        shape.lineWidth = 10
        shape.path = path.cgPath
        shape.strokeColor = UIColor.black.cgColor
        shape.fillColor = UIColor.clear.cgColor
        gradient.mask = shape

        layer.insertSublayer(gradient, at: 0)
    

【讨论】:

谢谢@rmaddy,但是我怎样才能从左到右渲染渐变呢? 我的答案中的代码确实从左到右呈现渐变。当这个类按原样复制到 Swift Playground 中,然后创建这个 View 类的实例时,生成的视图是椭圆形,左边是绿色,右边是红色。

以上是关于如何在 Swift 4 的 UIView 中创建带圆角的渐变边框的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QOpenGLTexture 中创建带 alpha 的纹理?

如何在 django 中创建带参数的链接

如何在 Android 中创建带圆角的 ListView?

如何在 Oracle 12c 中创建带条件的索引?

如何在React MUI中创建带标签的TextField

如何在 PySpark 中创建带偏移量的 InputDStream(使用 KafkaUtils.createDirectStream)?