You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发中如何为CAShapeLayer添加独立选中矩形外框

为CAShapeLayer添加选中状态外围矩形框的实现问题

我是Swift以及Core Animation的新手,想要给CAShapeLayer添加外围矩形框,就像示例图展示的效果,但目前不知道如何实现。

具体来说,我通过PocketSVG解析SVG图片,将UIBezierPath转换为CAShapeLayer后,把这些图层作为子图层添加到UIImageView上。

以下是我将Path转换为CAShapeLayer的代码:

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
}

以下是我将图层添加到UIImageView(变量名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)
}

我还为CAShapeLayer添加了TapGesture(点击手势)、RotateGesture(旋转手势)、ScaleGesture(缩放手势)和PanGesture(平移手势),代码如下:

@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,我知道这并不是合理的实现方式。

请问有什么方法可以实现类似示例图中的选中矩形外框效果?


内容的提问来源于stack exchange,提问作者Ali Akbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:54:06