如何在 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 的纹理?
如何在 PySpark 中创建带偏移量的 InputDStream(使用 KafkaUtils.createDirectStream)?