我使用此功能使用了很多渐变图:
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()
的viewDidLoad()
中调用UIViewController
,则渐变不会覆盖iPhone X +上的整个屏幕。但是,如果我调用self.view.layoutIfNeeded()
,它会使我的应用在iOS 9.x上崩溃并在iPhone 5 / 5s上表现异常。我真的不知道任何解决方法,需要帮助以了解其工作原理。 最佳答案
您正在drawGradient
中调用viewDidLoad
。还为时过早。您需要等待,直到自动版式调整了框架的大小。
将viewDidLoad
中的 call 移到viewDidLayoutSubviews
的替代中。不过请小心,因为viewDidLayoutSubviews
被多次调用了,因此请确保只调用一次drawGradient
。您可以在viewController中添加一个名为var appliedGradient = false
的属性,然后在应用渐变之前对其进行检查并将其翻转到true
。
对于UITableViewCell
和UICollectionViewCell
的自定义子类,请覆盖layoutSubviews
并在drawGradient
之后调用super.layoutSubviews()
。同样,请确保只调用一次。
注意:如果您的frame
可以调整大小(由于手机旋转)或不同的像元大小,则应跟踪上一个渐变层,并用viewt的viewDidLayoutSubviews
和像元的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)
}
}