ios - 使用 UIImageView 在 UIView 中切割透明孔

标签 ios swift uiimageview uibezierpath cgpath

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

enter image description here

我有一个相机覆盖图(屏幕中间的正方形)。

我查看了 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 是在 storyboard 中创建的,我在它上面使用的只是将它垂直和水平居中到 super View 的约束,如下所示:

enter image description here

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

enter image description here

如果有人可能知道是什么原因造成的或如何解决它,我将不胜感激,因为我似乎无法找到它。

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

            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

最佳答案

很有可能...

您创建 mask 的时间过早 - 在自动布局调整/定位 View 之前。

像这样尝试:

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

    }

}

关于ios - 使用 UIImageView 在 UIView 中切割透明孔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62138657/

相关文章:

ios - 无法显示导航 View

ios - 如何更改didSelectRowAtIndexPath中单元格的背景图像

ios - 参数是未声明的类型?

ios - 如何将标签设置为 UIImageview 图像等于 iOS 中每个图像的数组索引?

swift - iOS 图表双倍于 Int Swift

ios - 将 UIButton 连接到关闭? (快速,目标 Action )

ios - 传输安全已阻止明文 HTTP

ios - 如何在 ios swift 中为事件设置自定义标识符?

swift - 与 Swift Where 子句混淆。

ios - 创建一个将迭代图像数组的 UIImageView