如何使用UIView的平移手势更新UIBezierpath和CAShapeLayer路径?

问题描述

'''

import UIKit

class CanvasView: UIView {
    var circleViewTag = 1000
    var coordinatePoints: [String] = ["243,103","534,86","243,286","426,286"] {
        didSet {
            self.updateCoordinateArray()
            self.drawPoints()
        }
    }
    
    fileprivate var coordArray: [CGPoint] = []
    var shape = CAShapeLayer()
    var path = UIBezierPath()
    /*// Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }*/
    
    private func drawPoints() -> Void {
        CommonMethods.printLog("\(coordinatePoints)")
        self.layer.addSublayer(shape)
        shape.opacity = 0.5
        shape.lineWidth = 2
        shape.lineJoin = CAShapeLayerLineJoin.miter
        shape.strokeColor = UIColor.white.cgColor
        shape.fillColor = UIColor(red: 1.0,green: 0.2,blue: 0.2,alpha: 0.2).cgColor
        
        if let firstCoord = self.coordArray.first {
            path.move(to: firstCoord)
        }
        for (index,cgPoint) in self.coordArray.enumerated() {
            self.drawCircularPoint(points: cgPoint)
            if index == 0 {
                continue
            }
            path.addLine(to: cgPoint)
        }
        path.close()
        shape.path = path.cgPath
        //self.drawLineBetweenPoints()
    }

    
    private func drawCircularPoint(points: CGPoint) -> Void {
        
        let circleView = UIView.init(frame: .zero)
        circleViewTag = circleViewTag + 1
        circleView.tag = circleViewTag
        circleView.frame.size = CGSize.init(width: 30.0,height: 30.0)
        circleView.layer.cornerRadius = 15.0
        circleView.center = points
        circleView.backgroundColor = .random()
        
        let panGesture = UIPanGestureRecognizer(target: self,action: #selector(self.draggedView(_:)))
        panGesture.view?.tag = circleView.tag
        circleView.isUserInteractionEnabled = true
        circleView.addGestureRecognizer(panGesture)
        
        self.addSubview(circleView)
    }
    
    @objc func draggedView(_ sender:UIPanGestureRecognizer){
        guard let getTag = sender.view?.tag else { return }
        if let viewToDrag = self.viewWithTag(getTag) as? UIView {
            var currentPoint: CGPoint = .zero
            if path.contains(viewToDrag.center) {
                print("YES")
                
                currentPoint = path.currentPoint
                
            }
            
            let translation = sender.translation(in: self)
            viewToDrag.center = CGPoint(x: viewToDrag.center.x + translation.x,y: viewToDrag.center.y + translation.y)
            sender.setTranslation(CGPoint.zero,in: self)
            
            if sender.state == .began && currentPoint != .zero {
                let coordinateIndex =  self.coordArray.firstIndex { (cgpoint) -> Bool in
                    if currentPoint == cgpoint {
                        return true
                    }
                    return false
                }
                
                if coordinateIndex != nil {
                    self.coordArray[coordinateIndex!] = viewToDrag.center
                    self.shape.removeFromSuperlayer()
                    self.path.removeAllPoints()
                    self.setNeedsDisplay()
                    
                    self.layer.addSublayer(self.shape)
                    self.shape.opacity = 0.5
                    self.shape.lineWidth = 2
                    self.shape.lineJoin = CAShapeLayerLineJoin.miter
                    self.shape.strokeColor = UIColor.white.cgColor
                    self.shape.fillColor = UIColor(red: 1.0,alpha: 0.2).cgColor
                    
                    
                    if let firstCoord = self.coordArray.first {
                        path.move(to: firstCoord)
                    }
                    for (index,cgPoint) in self.coordArray.enumerated() {
                        //self.drawCircularPoint(points: cgPoint)
                        if index == 0 {
                            continue
                        }
                        path.addLine(to: cgPoint)
                    }
                    path.close()
                    shape.path = path.cgPath
                }
                
                
            }

        }
        //self.bringSubviewToFront(viewDrag)
    }
    
    private func updateCoordinateArray() -> Void {
        for singleCoordinate in self.coordinatePoints {
            if singleCoordinate.contains(",") == true {
            
                let splitCoordinate = singleCoordinate.split(separator: ",")
                
                if splitCoordinate.count == 2 {
                    let xPos = CGFloat(Float(splitCoordinate[0]) ?? 0.0)
                    let yPos = CGFloat(Float(splitCoordinate[1]) ?? 0.0)
                    let cgPoint = CGPoint(x: xPos,y: yPos)
                    
                    self.coordArray.append(cgPoint)
                }
            }
        }
        
        var penultimateIndex: Int?
        if let penultimateCoordinate = self.coordArray.penultimate() {
            penultimateIndex =  self.coordArray.firstIndex { (cgpoint) -> Bool in
                if penultimateCoordinate == cgpoint {
                    return true
                }
                return false
            }
        }
        var lastIndex: Int?
        if let lastCoordinate = self.coordArray.last {
            lastIndex =  self.coordArray.firstIndex { (cgpoint) -> Bool in
                if lastCoordinate == cgpoint {
                    return true
                }
                return false
            }
        }
        if penultimateIndex != nil && lastIndex != nil {
            self.coordArray.swapAt(penultimateIndex!,lastIndex!)
        }
    }

enter image description here

enter image description here

'''

我正在使用UIBezierpath和CAShapelayer创建一个多边形。在UIView的所有4个点上添加了平移手势。当我拖动点A,B,C,D时,预期的行为是bezierpath和CAShapelayer被更新了点。当用户拖动形状的内部时,所有路径都会更新。但是我无法更新路径和形状。有人可以帮我吗?

解决方法

为图层设置名称之外

var shape = CAShapeLayer()
shape.name = "name1"

然后,您可以通过先按名称搜索然后添加

来删除它,而不是进行更新。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...