微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在addLine方法

如何解决在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
 }
}

输出看起来像

enter image description here

我的第一个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方法。它只是将组件标记为脏,并将在下一个循环中重绘它。结果是即使您在同一循环(堆栈,方法...)中多次调用drawsetNeedsDisplay也只会被调用一次。因此,没有性能问题。

在使用图层的情况下也可以这样做。每当发生变化时,您都需要一个refresh方法。然后,此方法应创建子层或更正子层的框架,遮罩...,并且应删除draw方法。因此,可以使用其中一种方法,但不能同时使用两者。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。