【问题标题】:Cut transparent hole in UIView using UIImageView使用 UIImageView 在 UIView 中切割透明孔
【发布时间】:2020-06-01 18:33:43
【问题描述】:

我正在尝试为我的 QR 相机视图创建下面的图像。

我有一张用于相机叠加层的图像(即屏幕中间的正方形)。

我在 stackoverflow 上查看了类似的主题,并了解了如何从黑色背景(0.75% 透明)中剪切出相机叠加图像,以便将空白区域留在中间,但是我遇到了一些实际问题它的位置,我不知道是什么行为如此奇怪。

这是我用来创建背景黑色图像并切出中心正方形的代码:

            // Create a view filling the screen.
        let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))

        // Set a semi-transparent, black background.
        backgroundView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.75)

        // Create the initial layer from the view bounds.
        let maskLayer = CAShapeLayer()
        maskLayer.frame = backgroundView.bounds
        maskLayer.fillColor = UIColor.black.cgColor

        // Create the path.
        let path = UIBezierPath(rect: backgroundView.bounds)
        maskLayer.fillRule = CAShapeLayerFillRule.evenOdd

        // Append the overlay image to the path so that it is subtracted.
        path.append(UIBezierPath(rect: camOverlayImageView.frame))
        maskLayer.path = path.cgPath

        // Set the mask of the view.
        backgroundView.layer.mask = maskLayer

        // Add the view so it is visible.
        self.view.addSubview(backgroundView)

camOverlayImageView 是在情节提要中创建的,我在它上面使用的只是将其垂直和水平居中到超级视图的约束,如下所示:

但是,当我这样做时,这就是我在设备上得到的结果:

如果有人可能知道可能导致此问题的原因或如何解决它,将不胜感激,因为我似乎找不到它。

我当然可以手动移动框架并像这样偏移它,但这不是正确的方法:

            let overlayFrame = camOverlayImageView.frame
        // Append the overlay image to the path so that it is subtracted.
        path.append(UIBezierPath(rect: CGRect(
            x: overlayFrame.origin.x + 18,
            y: overlayFrame.origin.y - 6,
            width: overlayFrame.size.width,
            height: overlayFrame.size.height))
        )
        maskLayer.path = path.cgPath

而不是做我以前做的事情:

path.append(UIBezierPath(rect: camOverlayImageView.frame))
maskLayer.path = path.cgPath

【问题讨论】:

    标签: ios swift uiimageview uibezierpath cgpath


    【解决方案1】:

    很有可能……

    在自动布局调整视图大小/定位视图之前,您创建蒙版太早了。

    试试这样:

    class HoleInViewController: UIViewController {
    
        @IBOutlet var camOverlayImageView: UIView!
    
        let backgroundView: UIView = {
            let v = UIView()
            v.translatesAutoresizingMaskIntoConstraints = false
            v.backgroundColor = UIColor.black.withAlphaComponent(0.75)
            return v
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(backgroundView)
            NSLayoutConstraint.activate([
                backgroundView.topAnchor.constraint(equalTo: view.topAnchor),
                backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                backgroundView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            ])
    
        }
    
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
    
            // Create the initial layer from the view bounds.
            let maskLayer = CAShapeLayer()
            maskLayer.frame = backgroundView.bounds
            maskLayer.fillColor = UIColor.black.cgColor
    
            // Create the path.
            let path = UIBezierPath(rect: backgroundView.bounds)
            maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
    
            // Append the overlay image to the path so that it is subtracted.
            path.append(UIBezierPath(rect: camOverlayImageView.frame))
            maskLayer.path = path.cgPath
    
            // Set the mask of the view.
            backgroundView.layer.mask = maskLayer
    
        }
    
    }
    

    【讨论】:

    • 如何设置透明正方形扫描视图的圆角半径??
    • @AtulParmar - 对于这个非常简单的示例,您可以使用 path.append(UIBezierPath(roundedRect: camOverlayImageView.frame, cornerRadius: 60.0)) 代替 path.append(UIBezierPath(rect: camOverlayImageView.frame))(例如,获得 60-pt 圆角)
    猜你喜欢
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多