如何旋转 CALayer 并在设备旋转时覆盖完整的视图?

How to rotate CALayer and cover complete View on device rotation?

提问人:Andrei Herford 提问时间:3/7/2023 最后编辑:Andrei Herford 更新时间:3/7/2023 访问量:48

问:

我通过添加 .虽然这工作正常,但在旋转设备和视图 + 图层时会出现小故障。在短时间内,图层不会覆盖整个视图,但视图/背景是可见的。如何避免这种情况?UIViewCAGradientLayer

法典:

class BackgroundView: UIView {
    private let gradient : CAGradientLayer = CAGradientLayer()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    func commonInit() {
        gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
        self.layer.insertSublayer(gradient, at: 0)
    }
    
    
    // Option 1: Adjust layer on sublayer layout
    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        gradient.frame = self.bounds
    }
    
    // Option 2: Adjust layer on subview layout
    override func layoutSubviews() {
        super.layoutSubviews()
        gradient.frame = self.bounds
    }

    // Option 3: Adjust layer on trait collection change
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        gradient.frame = self.bounds
    }
}

结果是完全相同的,无论是否 或 jused,或两者兼而有之。在所有情况下,图层在旋转过程中都会正确地调整为新的最终大小/边界,但与视图本身的方式不同。因此,视图及其背景在短时间内可见。如何避免这种情况?Option1Option2

渐变应始终覆盖整个视图。

我发现了一些关于如何使用视图旋转图层的问题。但是,所有答案都提供了我尝试过的选项。我做错了什么,或者这个故障正常吗?

编辑:在特征集合更改时更新梯度边界具有相同的效果。

iOS Swift UIView Calayer 屏幕旋转

评论


答:

0赞 DonMag 3/7/2023 #1

您可以覆盖视图的“基础层”,而不是添加一个作为子层。layerClassCAGradientLayer

看看这个:

class MyGradientView: UIView {
    
    // this allows us to use the "base" layer as a gradient layer
    //  instead of adding a sublayer
    lazy var gradLayer: CAGradientLayer = self.layer as! CAGradientLayer
    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() {
        gradLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
        // other initial properties
    }
    
}