CAGradientLayer 旋转到 Landscape 后只占一半屏幕

Posted

技术标签:

【中文标题】CAGradientLayer 旋转到 Landscape 后只占一半屏幕【英文标题】:CAGradientLayer only takes up half the screen after rotating to Landscape 【发布时间】:2019-01-03 22:04:11 【问题描述】:

渐变填充了我的应用程序的背景。我正在使用以下效果很好:

gradientLayer.frame = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: dWidth, height: dHeight))

但是,当我旋转时,渐变只填满了一半的屏幕,大概是因为旋转使框架发生变化

我尝试了以下方法:

let deviceScale = UIScreen.main.scale

gradientLayer.frame = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: dWidth*deviceScale, height: dHeight*Scale))

虽然这解决了旋转问题,但我相信这是因为渐变框架现在是巨大的。事实上,我现在拥有的不是渐变,它主要是一种纯色(大概是因为看不到后面的颜色,因为框架很大)。

我怎样才能让渐变填充背景并与旋转一起使用?

谢谢


1 月 4 日更新:

感谢您的回复。这似乎对我不起作用。我正在使用一个函数来设置渐变背景:

func setGradientBackground(col1: UIColor, col2: UIColor, SPNUM: CGFloat, EPNUM: CGFloat, viewName: String) 

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = theView.bounds
    gradientLayer.colors = [col1.cgColor, col2.cgColor]
    gradientLayer.startPoint = CGPoint(x: SPNUM, y: 0)
    gradientLayer.endPoint = CGPoint(x: EPNUM, y: 1)

    let sublayersCount = view.layer.sublayers?.count ?? 0
    view.layer.insertSublayer(gradientLayer, at: UInt32(sublayersCount))

    view.layer.layoutSublayers()
    view.bringSubviewToFront(theView)

gradientLayer.frame 是在函数内设置的,如上所示

我已尝试添加以下内容,但旋转为横向后渐变不会调整大小:

override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()
    gradientLayer.frame = theView.bounds
    print("msg1")

有什么想法吗?谢谢

【问题讨论】:

【参考方案1】:

如果您的渐变层设置在UIView 中,您应该覆盖layoutSubviews,它会在视图大小发生变化时调用,并在那里将框架设置为所需的大小。例如:

override func layoutSubviews() 
    super.layoutSubviews() // make sure to call super first!
    gradientLayer.frame = self.bounds // fill the view

如果您在UIViewController 中设置层,则可以改写viewDidLayoutSubviews(同时确保首先调用super 实现)。

一般来说,由于您不能对图层使用自动布局,因此您应该重写其中一种方法来完成图层的所有布局。

【讨论】:

我尝试使用 layoutSubviews,但渐变在旋转后没有调整大小。请参阅上面的“1 月 4 日更新”。会不会是因为我使用了一个函数来设置渐变背景,而gradientLayer.frame是在函数内部设置的? 嗯,在更新的第一个代码 sn-p 中,您从头开始创建一个新的渐变层。您在viewDidLayoutSubviews 中引用的是什么gradientLayer 属性?我怀疑您实际上可能没有对渐变层的引用。 另一个提示 - 您可以使用 addSublayer 而不是计算当前层数以在顶部添加新层。 这个 sn-p 为我正确调整大小 - 我将渐变层创建为视图控制器的属性,因此我可以在 viewDidLayoutSubviews 中引用它:gist.github.com/kylebshr/ce826ff88b37d1b5499915a8f3caa16a

以上是关于CAGradientLayer 旋转到 Landscape 后只占一半屏幕的主要内容,如果未能解决你的问题,请参考以下文章

CAGradientLayer 自转

CAGradientLayer 的中心在旋转动画上返回错误的位置

CAGradientLayer 发送到后面

CF1166C A Tale of Two Lands

如何将 CAGradientLayer 添加到 CAShapeLayer?

[TypeScript] Using Exclude and RootDir until File Globs Lands in 2.0.