【问题标题】:How to update UIBezierpath and CAShapeLayer path with pan gesture of UIView?如何使用 UIView 的平移手势更新 UIBezierpath 和 CAShapeLayer 路径?
【发布时间】:2020-12-09 17:12:16
【问题描述】:

'''

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, 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.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!)
        }
    }

'''

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

【问题讨论】:

    标签: swift animation draw uibezierpath cashapelayer


    【解决方案1】:

    为层设置名称

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

    然后,您可以先按名称搜索删除它,然后再添加,而不是更新它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      相关资源
      最近更新 更多