我正在使用这个函数进行大量的渐变绘制:
func drawGradient(colors: [CGColor], locations: [NSNumber]) {
let gradientLayer = CAGradientLayer()
gradientLayer.frame.size = self.frame.size
gradientLayer.frame.origin = CGPoint(x: 0.0,y: 0.0)
gradientLayer.colors = colors
gradientLayer.locations = locations
print(self.frame.size)
self.layer.insertSublayer(gradientLayer, at: 0)
}
问题在于,如果我不在self.view.layoutIfNeeded()
的{{1}}中拨打viewDidLoad()
我的渐变不会覆盖iPhone X +上的整个屏幕。但是,如果我打电话给UIViewController
,它会让我的应用程序在iOS 9.x上崩溃并在iPhone 5/5上表现得很奇怪。我真的不知道任何解决方法,需要帮助才能理解它是如何工作的。
答案 0 :(得分:2)
您正在drawGradient
中呼叫viewDidLoad
。那太早了。您需要等到自动布局确定框架大小。
将viewDidLoad
中的来电移至viewDidLayoutSubviews
的覆盖。但要小心,因为viewDidLayoutSubviews
被多次调用,所以请确保只调用drawGradient
一次。您可以向viewController添加一个名为var appliedGradient = false
的属性,然后在应用渐变之前检查它并将其翻转到true
。
对于UITableViewCell
和UICollectionViewCell
的自定义子类,请覆盖layoutSubviews
并在drawGradient
后调用super.layoutSubviews()
。再次确保你只调用一次。
注意:如果frame
可以调整大小(由于手机的旋转)或不同的单元格大小,您应该跟踪上一个渐变图层并将其替换为新图层在viewDidLayoutSubviews
中为您的viewController和layoutSubviews
为您的单元格。
我在这里修改了您的drawGradient
,以创建一个名为applyGradient
的全局函数,为视图添加渐变。如果有一个渐变图层,它将替换先前的渐变图层:
func applyGradient(colors: [CGColor], locations: [NSNumber], to view: UIView, replacing prior: CALayer?) -> CALayer {
let gradientLayer = CAGradientLayer()
gradientLayer.frame.size = view.frame.size
gradientLayer.frame.origin = CGPoint(x: 0.0,y: 0.0)
gradientLayer.colors = colors
gradientLayer.locations = locations
print(view.frame.size)
if let prior = prior {
view.layer.replaceSublayer(prior, with: gradientLayer)
} else {
view.layer.insertSublayer(gradientLayer, at: 0)
}
return gradientLayer
}
它的用法如下:
class ViewController: UIViewController {
// property to keep track of the gradient layer
var gradient: CALayer?
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
gradient = applyGradient(colors: [UIColor.red.cgColor, UIColor.yellow.cgColor],
locations: [0.0, 1.0], to: self.view, replacing: gradient)
}
}