我想在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宽度。
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)
请帮助。预先感谢。
答案 0 :(得分:2)
修改
我想从左到右设置边框
您需要更改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)
截屏:
答案 1 :(得分:1)
问题在于,贝塞尔曲线路径未在其边界内绘制。它是围绕边界绘制的。因此,笔划宽度的一半在内部,一半在外部。您需要调整范围以解决此问题。
将进入贝塞尔曲线路径的帧从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)
}
}