ios CALayer在存储到属性中时消失

46qrfjad  于 12个月前  发布在  iOS
关注(0)|答案(2)|浏览(99)

我有一个自定义的UIPresentationController,其中我覆盖了presentedView,如下所示:

override var presentedView: UIView? {
        guard let view = super.presentedView else { return nil }
        
        let shadowLayer = CALayer()
        shadowLayer.shadowPath = .init(rect: view.bounds, transform: .none)
        shadowLayer.shadowRadius = 6
        shadowLayer.shadowColor = .init(gray: 0, alpha: 0.15)
        shadowLayer.backgroundColor = view.layer.backgroundColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = .init(width: 0, height: -10)
        shadowLayer.shouldRasterize = true
        shadowLayer.rasterizationScale = UIApplication.screen?.scale ?? 1.0
        
        view.layer.insertSublayer(shadowLayer, at: 0)
        shadowLayer.position = view.layer.position
        shadowLayer.bounds = view.bounds
        view.layer.masksToBounds = false
        
        return view
    }

然后为了效率,我想为什么每次计算presetedView时都要创建一个新的CALayer,并决定将层作为类的属性,只更新shadowPath。之后,该层不再可见,也不再位于视图层次结构中。我也尝试插入子层只有一次,通过检查层是否存在于子层,但它没有帮助
有人知道我错过了什么吗?

更新:申报房产

private let shadowLayer = {
        let shadowLayer = CALayer()
        shadowLayer.shadowRadius = 6
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = .init(width: 0, height: -10)
        shadowLayer.shouldRasterize = true
        shadowLayer.rasterizationScale = UIApplication.screen?.scale ?? 1.0
        shadowLayer.masksToBounds = false
        return shadowLayer
    }()

从这里删除了初始化代码。之后,图层消失

override var presentedView: UIView? {
        guard let view = super.presentedView else { return nil }
        

        shadowLayer.shadowPath = .init(rect: view.bounds, transform: .none)

        shadowLayer.shadowColor = .init(gray: 0, alpha: 0.15)
        shadowLayer.backgroundColor = view.layer.backgroundColor

        
        view.layer.insertSublayer(shadowLayer, at: 0)
        shadowLayer.position = view.layer.position
        shadowLayer.bounds = view.bounds
        view.layer.masksToBounds = false
        
        return view
    }
nc1teljy

nc1teljy1#

您可以简单地添加代码将shadowLayer定义为示例变量,并同时初始化它:

var shadowLayer = CALayer()

(You也可以使其成为一个懒惰的属性。)
对上面的代码进行修改,然后在代码中引用现有的shadowLayer,而不是在函数中定义(并初始化)它。

mtb9vblg

mtb9vblg2#

原来我是计算层positionshadowPath错误!由于子层坐标系是相对于上层坐标系的,所以我们应该在视图bounds而不是frame内绘制路径,并手工计算框架的中心点

override var presentedView: UIView? {
        guard let view = super.presentedView else { return nil }
        
        
        shadowLayer.shadowPath = .init(rect: view.bounds, transform: .none)
        shadowLayer.position = .init(x: view.bounds.midX, y: view.bounds.midY)
        shadowLayer.bounds = view.bounds
        shadowLayer.backgroundColor = view.layer.backgroundColor

        
        if shadowLayer.superlayer == nil {
            view.layer.insertSublayer(shadowLayer, below: nil)
        }
        
        view.layer.masksToBounds = false
        
        return view
    }

相关问题