ios - layoutIfNeeded 函数行为

标签 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.colors = colors
    gradientLayer.locations = locations
    print(self.frame.size)
    self.layer.insertSublayer(gradientLayer, at: 0)
}

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

最佳答案

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

对于 UITableViewCell 的自定义子类和UICollectionViewCell ,覆盖layoutSubviews并调用drawGradient之后super.layoutSubviews() 。再次强调,请确保只调用一次。


注意:如果您的frame可能会调整大小(由于手机旋转)或不同的单元格大小,您应该跟踪前一个渐变层并将其替换为 viewDidLayoutSubviews 中的新渐变层对于你的 viewController 和 layoutSubviews为了您的细胞。

在这里我修改了你的drawGradient创建一个名为 applyGradient 的全局函数为 View 添加渐变。如果有的话,它会替换之前的渐变层:

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

关于ios - layoutIfNeeded 函数行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41332022/

相关文章:

java - 我应该为这个应用程序使用哪个布局管理器?

ios - 触摸 move UILabel 一直有效,直到值修复 - 错误还是功能?

ios - 如何使用 Moya 取消多个网络请求

快速通用和动态方法调度

android - FindViewByID(...) 在设置内容 View 和清理项目后返回 null

qt - 如何限制 Qt Designer 布局的增长(大小)?

iOS堆栈 View 约束问题

ios - '-[UITableViewController setRootController :]: unrecognized selector sent to instance

iphone - Google 帐户 OAuth2 支持框架?

ios - 如何以编程方式在 UITableViewCell 中添加 UIView?