我使用此功能使用了很多渐变图:

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

对于UITableViewCellUICollectionViewCell的自定义子类,请覆盖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)
    }
}

10-08 14:47