繁体   English   中英

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

[英]How to create Gradient border with rounded corners at UIView in Swift 4

我想在UIView中使用从左到右的渐变设置边框颜色[红色,绿色]。 像例子:

在此处输入图片说明

我尝试了以下代码:-

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,但是它在角落和水平/垂直方向仅显示了5的宽度10。
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)

在此处输入图片说明

请帮忙。 提前致谢。

编辑

我想从左到右设置边框

您需要更改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添加inset解决了这个问题:

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

问题在于贝塞尔曲线路径未在其边界内绘制。 它是围绕边界绘制的。 因此,笔划宽度的一半在内部,一半在外部。 您需要调整范围以处理此问题。

将传递到self.bounds self.bounds.insetBy(dx: 5, dy: 5)路径中的帧从self.boundsself.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)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM