如何解决在addLine方法
我正在尝试使用bezierPath绘制视图,我的代码是?
class auctionCollectionView : UIView{
let gradient = CAGradientLayer()
private var shapeLayer: CALayer?
private func addShape() {
let shapeLayer = CAShapeLayer()
shapeLayer.path = mys2().cgPath
shapeLayer.strokeColor = UIColor.lightGray.cgColor
self.shapeLayer = shapeLayer
let colorTop = UIColor(hexFromString: "#101820").cgColor
let colorBottom = UIColor(hexFromString: "#101820").cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.mask = shapeLayer
gradientLayer.colors = [colorTop,colorBottom]
gradientLayer.locations = [0.0,1.0]
gradientLayer.frame = mys2().bounds
self.layer.insertSublayer(gradientLayer,at:0)
}
override func draw(_ rect: CGRect) {
self.addShape()
}
func mys2() -> UIBezierPath {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0,y: self.frame.height/4)) // start top left
path.addQuadCurve(to: CGPoint(x: self.frame.width,y:self.frame.height/4),controlPoint: CGPoint(x: self.frame.width/2,y: 0 ))
path.addLine(to: CGPoint(x: self.frame.width,y: self.frame.height * 3/4))
path.addQuadCurve(to: CGPoint(x: 0,y: self.frame.height * 3/4),y:self.frame.height / 2))
path.addLine(to: CGPoint(x: 0,y: self.frame.height/4))
path.close()
return path
}
}
输出看起来像
我的第一个QuadCurve看起来不错,但是当我尝试将其从maxX (self.frame.width)
,maxY ( self.frame.height * 3/4)
添加到minX ( 0)
,maxY (self.frame.height * 3/4)
与CGPoint(x: self.frame.width/2,y:self.frame.height / 2)
时,就像添加线
我在这里想念什么?问候!
解决方法
您的路径似乎还可以,但是我担心您的问题是覆盖draw
方法时要调用的内容。
您应该添加一次图层,然后再进行管理。或者,您应该使用draw rect绘制所有内容而不使用图层。在这种情况下,我建议第二个。我不确定完全的实现方式,但是从复制路径并查看渐变代码来看,它可能类似于以下内容:
@IBDesignable class DrawingView: UIView {
@IBInspectable var topColor: UIColor? = .red
@IBInspectable var bottomColor: UIColor? = .blue
private func mys2() -> UIBezierPath {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0,y: self.frame.height/4)) // start top left
path.addQuadCurve(to: CGPoint(x: self.frame.width,y:self.frame.height/4),controlPoint: CGPoint(x: self.frame.width/2,y: 0 ))
path.addLine(to: CGPoint(x: self.frame.width,y: self.frame.height * 3/4))
path.addQuadCurve(to: CGPoint(x: 0,y: self.frame.height * 3/4),y:self.frame.height / 2))
path.addLine(to: CGPoint(x: 0,y: self.frame.height/4))
path.close()
return path
}
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext(),let topColor = topColor,let bottomColor = bottomColor else {
return
}
// Save because of clipping
context.saveGState()
// Add clipping from my path
mys2().addClip()
let locations: [CGFloat] = [0.0,1.0]
let colors = [topColor.cgColor,bottomColor.cgColor]
if let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(),colors: colors as CFArray,locations: locations) {
context.drawLinearGradient(gradient,start: CGPoint.zero,end: CGPoint(x: 0.0,y: frame.size.height),options: CGGradientDrawingOptions(rawValue: 0))
}
context.restoreGState()
}
}
因此,我们可以仅使用裁剪来代替蒙版,这是蒙版首先在图层中执行的操作。渐变代码有些不同,但仍然足够相似。
现在请注意,只要需要重绘视图,就会调用此方法。要强制重绘,您需要调用setNeedsDisplay
。因此,类似以下内容可能很常见:
@IBInspectable var topColor: UIColor? = .red { didSet { refresh() } }
@IBInspectable var bottomColor: UIColor? = .blue { didSet { refresh() } }
override var frame: CGRect { didSet { refresh() } }
override func layoutSubviews() {
super.layoutSubviews()
refresh()
}
private func refresh() { setNeedsDisplay() }
因此,基本上,您在以下情况下会强制其重绘:
- 任何颜色都会改变
- 正在设置帧(通常在不使用自动布局的情况下)
- 子视图正在布局(使用自动布局时的常见情况)
请注意,调用setNeedsDisplay
不会立即强制重新加载并调用draw
方法。它只是将组件标记为脏,并将在下一个循环中重绘它。结果是即使您在同一循环(堆栈,方法...)中多次调用draw
,setNeedsDisplay
也只会被调用一次。因此,没有性能问题。
在使用图层的情况下也可以这样做。每当发生变化时,您都需要一个refresh
方法。然后,此方法应创建子层或更正子层的框架,遮罩...,并且应删除draw
方法。因此,可以使用其中一种方法,但不能同时使用两者。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。