向掩模图层添加边框

问题描述 投票:3回答:1

我正在尝试使用遮罩层制作自定义形状UIButton,我很成功

extension UIButton { 

  func mask(withImage image : UIImage , frame : CGRect ){

        let maskingLayer = CAShapeLayer()
        maskingLayer.frame = frame
        maskingLayer.contents = image.cgImage
        self.layer.mask = maskingLayer
    }
}

但我想在遮罩层添加边框(笔划)以指示已选择此按钮。

我尝试在遮罩层添加子图层

button.mask?.layer.borderColor = UIColor.black.cgColor
button.mask?.layer.borderWidth = 4

但由于按钮形状仍为矩形,因此无效。

我知道我可以使用CGMutablePath来定义形状

func mask(withPath path: CGMutablePath , frame : CGRect , color : UIColor) {

    let mask = CAShapeLayer()
    mask.frame = frame
    mask.path = path
    self.layer.mask = mask

    let shape = CAShapeLayer()
    shape.frame = self.bounds
    shape.path = path
    shape.lineWidth = 3.0
    shape.strokeColor = UIColor.black.cgColor
    shape.fillColor = color.cgColor

    self.layer.insertSublayer(shape, at: 0)
   //  self.layer.sublayers![0].masksToBounds = true
}

但是使用路径绘制这样复杂的形状是非常困难的

enter image description here

任何帮助,将不胜感激。

ios swift calayer cashapelayer
1个回答
3
投票

我能够使用PocketSVG从图像(.svg)获取CGPath

但我面临另一个问题,即路径的规模等于原始的SVG,所以我设法缩放路径以适应框架,这里是完整的代码: -

extension UIView {
    func mask(withSvgName ImageName : String , frame : CGRect , color : UIColor){

            let svgutils = SvgUtils()
            let paths = svgutils.getLayerFromSVG(withImageName: ImageName)
            let mask = CAShapeLayer()
            mask.frame = frame
            let newPath = svgutils.resizepath(Fitin: frame, path: paths[0].cgPath)
            mask.path = newPath
            self.layer.mask = mask

            let shape = CAShapeLayer()
            shape.frame = self.bounds
            shape.path = newPath
            shape.lineWidth = 2.0
            shape.strokeColor = UIColor.black.cgColor
            shape.fillColor = color.cgColor
            self.layer.insertSublayer(shape, at: 0)

        }
}

和实用程序类

import Foundation
import PocketSVG

class SvgUtils{


    func getLayerFromSVG(withImageName ImageName : String ) -> [SVGBezierPath]{

        let url = Bundle.main.url(forResource: ImageName, withExtension: "svg")!

        var paths = [SVGBezierPath]()

        for path in SVGBezierPath.pathsFromSVG(at: url) {

            paths.append(path)
        }

        return paths
    }

    func resizepath(Fitin frame : CGRect , path : CGPath) -> CGPath{


        let boundingBox = path.boundingBox
        let boundingBoxAspectRatio = boundingBox.width / boundingBox.height
        let viewAspectRatio = frame.width  / frame.height
        var scaleFactor : CGFloat = 1.0
        if (boundingBoxAspectRatio > viewAspectRatio) {
            // Width is limiting factor

            scaleFactor = frame.width / boundingBox.width
        } else {
            // Height is limiting factor
            scaleFactor = frame.height / boundingBox.height
        }


        var scaleTransform = CGAffineTransform.identity
        scaleTransform = scaleTransform.scaledBy(x: scaleFactor, y: scaleFactor)
        scaleTransform.translatedBy(x: -boundingBox.minX, y: -boundingBox.minY)

        let scaledSize = boundingBox.size.applying(CGAffineTransform (scaleX: scaleFactor, y: scaleFactor))
       let centerOffset = CGSize(width: (frame.width - scaledSize.width ) / scaleFactor * 2.0, height: (frame.height - scaledSize.height) /  scaleFactor * 2.0 )
        scaleTransform = scaleTransform.translatedBy(x: centerOffset.width, y: centerOffset.height)
        //CGPathCreateCopyByTransformingPath(path, &scaleTransform)
        let  scaledPath = path.copy(using: &scaleTransform)


        return scaledPath!
    }

}

并简单地使用它

button.mask(withSvgName: "your_svg_fileName", frame: button.bounds, color: UIColor.green)
© www.soinside.com 2019 - 2024. All rights reserved.