【问题标题】:Draw rectangle around CAShape Layer在 CAShape 图层周围绘制矩形
【发布时间】:2021-12-17 18:51:44
【问题描述】:

我是 Swift 和 Core Animation 的新手。我想在 CAShapeLayer 周围创建矩形框,就像在 image 中一样,但我不知道。

详细来说,我正在通过PocketSVG 解析 SVG 图像并将其 UIBezierPath 转换为 CAShapeLayer,然后我将这些图层添加到 UI Image View 作为子层

这是我将 Path 转换为 CaShape Layer 的代码。

fileprivate func createLayer(path: SVGBezierPath) -> CAShapeLayer {
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.cgPath
    if let any = path.svgAttributes["stroke"] {
        shapeLayer.strokeColor = (any as! CGColor)
    }
    
    if let any = path.svgAttributes["fill"] {
        shapeLayer.fillColor = (any as! CGColor)
    }
    return shapeLayer
}

下面是代码,我在其中向 UIImage View (backgroundIV) 添加图层

        for path in paths {
        path.apply(.init(scaleX: scale, y: scale))
        let layer = createLayer(path: path)
        layer.frame = self.backgroundIV.bounds
        self.backgroundIV.layer.addSublayer(layer)
    }

我还将TapGesture、RotateGesture、ScaleGesture和PanGesture添加到CA Shape Layers,下面是代码。

    @objc func rotateLayer(_ sender: UIRotationGestureRecognizer) {
    selectedLayer?.setAffineTransform(CGAffineTransform(rotationAngle: sender.rotation))
}

@objc func selectLayer(_ sender: UITapGestureRecognizer) {
    let point = sender.location(in: self.backgroundIV)
    guard let layers = self.backgroundIV.layer.sublayers
    else { return }
    var hitLayers: [CAShapeLayer] = []
    
    selectedLayer?.lineWidth = CGFloat(0)
    
    for subLayer in layers {
        if let thisLayer = subLayer as? CAShapeLayer,
           let pth = thisLayer.path {
            let layerPoint: CGPoint = thisLayer.convert(point, from: self.backgroundIV.layer)
            if pth.contains(layerPoint) {
                hitLayers.append(thisLayer)
            }
        }
    }
    
    selectedLayer = hitLayers.last
    selectedLayer?.strokeColor = UIColor.red.cgColor
    selectedLayer?.lineWidth = CGFloat(3)
    selectedLayerRect = CGRect(origin: point, size: CGSize(width: 100, height: 100))
    showPopupMenu()
    
}

@objc func moveLayer(_ recognizer: UIPanGestureRecognizer) {
    let p = recognizer.location(in: self.backgroundIV)
    selectedLayer?.position = p
}

@objc func scaleLayer(_ sender: UIPinchGestureRecognizer) {
    selectedLayer?.transform = CATransform3DMakeScale(sender.scale, sender.scale, 1)
}

SelectLayer 方法的最后几行中,我通过增加其笔触宽度和颜色来突出显示所选图层。

selectedLayer?.strokeColor = UIColor.red.cgColor
selectedLayer?.lineWidth = CGFloat(3)

当我取消选择图层时,我只是将它的 lineWidth 值设置为 0,这不是一个好习惯。

有没有办法像image那样创建矩形框?

【问题讨论】:

    标签: ios swift svg core-animation pocketsvg


    【解决方案1】:

    如果我理解正确,您的问题是“如何绘制虚线轮廓”?

    如果是这样,您可以在形状图层上设置.lineDashPattern

    例如:

        selectedLayer?.strokeColor = UIColor.red.cgColor
        selectedLayer?.lineWidth = 3.0
        
        // set the dash pattern for the stroke
        selectedLayer?.lineDashPattern = [10, 10]
    

    【讨论】:

      【解决方案2】:

      试试这个..
      我希望这对你有帮助......??

      import UIKit
      class ViewController : UIViewController {
      
      let containerView: UIView = {
          let view = UIView()
          view.backgroundColor = .clear
          return view
      }()
      
      override func viewDidLoad() {
          super.viewDidLoad()
          
          containerView.frame = CGRect(x: view.frame.width/2 - 100, y: view.frame.height/2 - 100, width: 200, height: 200)
          view.addSubview(containerView)
          
          drawRectangle()
      }
      
      private func drawRectangle() {
          
          let path = UIBezierPath()
          path.move(to: CGPoint(x: 0, y: 0))
          path.addLine(to: CGPoint(x: 200, y: 0))
          path.addLine(to: CGPoint(x: 200, y: 200))
          path.addLine(to: CGPoint(x: 0, y: 200))
          path.addLine(to: CGPoint(x: 0, y: 0))
          
          let shapeLayer = CAShapeLayer()
          shapeLayer.path = path.cgPath
          shapeLayer.strokeColor = UIColor.red.cgColor
          shapeLayer.fillColor = UIColor.black.cgColor
          shapeLayer.lineWidth = 3
          
          containerView.layer.addSublayer(shapeLayer)
          }
      }
      

      【讨论】:

        【解决方案3】:

        这是我的问题的答案

            var selectedLayer: CAShapeLayer! {
            didSet {
                guard let layer = selectedLayer else {return}
                box.frame = layer.path?.boundingBox ?? CGRect()
                box.borderWidth = layer.contentsScale * 3
                box.borderColor = UIColor.red.cgColor
                self.updateControlView()
                layer.addSublayer(box)
            }
            willSet {
                self.controlView.isHidden = true
                box.removeFromSuperlayer()
            }
        }
        

        Output

        【讨论】:

          【解决方案4】:

          如果您想在图层框架周围绘制一个框,这很容易。只需设置aLayer.borderWidth=1aLayer.borderColor=UIColor.someColor.cgColor

          系统会为您在图层周围添加边框。

          但是,如果您的图层的框架比它们包含的路径大,您的矩形可能会比您想要的大。

          【讨论】:

          • 我正在这样做,但我想在选择图层时制作矩形框
          • “选择图层”是什么意思? iOS 没有这个概念。这是你必须在你的程序中实现的东西。您需要在包含形状图层的父图层上添加 hitTest() 方法,跟踪选择了哪些图层,并以用户身份在 1 和 0 之间切换所选图层的 borderWidth选择/取消选择图层。
          • 如果您在实施层选择系统方面需要帮助,您需要大大扩展您的问题,以解释您的应用程序的结构、“选择层”的含义等,并描述您的目标工作。
          • 我根据您的建议编辑问题
          猜你喜欢
          • 1970-01-01
          • 2022-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-12
          • 2018-02-13
          • 2020-08-04
          相关资源
          最近更新 更多