Ios 布局需要的函数行为

Ios 布局需要的函数行为,ios,swift,layout,Ios,Swift,Layout,我使用了很多渐变绘图,使用这个函数: 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.color

我使用了很多渐变绘图,使用这个函数:

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)
}

问题是,如果我没有在
UIViewController
viewDidLoad()
中调用
self.view.layoutifneed()
,我的渐变不会覆盖iPhone X+的整个屏幕。但是如果我调用self.view.layoutifneed(),我的应用程序就会在iOS 9.x上崩溃,在iPhone 5/5s上表现得很怪异。我真的不知道任何解决方法,需要帮助才能理解它是如何工作的。

您正在
viewDidLoad
中调用
drawGradient
。这还为时过早。您需要等待自动布局调整框架的大小。
viewdiload
中的调用移动到对
viewdilayoutsubviews
的覆盖。但是要小心,因为调用了多次
viewdilayoutsubviews
,所以请确保只调用一次
drawGradient
。您可以向viewController添加一个名为
var appliedGradient=false
的属性,然后在应用渐变之前检查该属性并将其翻转为
true

对于
UITableViewCell
UICollectionViewCell
的自定义子类,重写
layoutSubviews
并在
super.layoutSubviews()之后调用
drawGradient
。再一次,确保只给它打一次电话


注意:如果您的
框架
可能会调整大小(由于手机的旋转)或不同的手机大小,您应该跟踪上一个渐变层,并在viewController的
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)
    }
}

当你调用
drawGradient
时,你必须确保视图具有正确的帧。是的,我知道,但我需要调用单元格内部的设置等,我必须强制视图布局,但这会使我的应用程序在iOS 9.x上崩溃。你在哪里调用
drawGradient
?当前在
viewDidLoad
和单元格的设置中(
cellForRowAt
)将
viewdiload
中的调用移动到
viewdilayoutsubviews
。您需要等待自动布局调整帧的大小。