使用 NSLayoutAnchor 不好吗?

Is using NSLayoutAnchor bad?

我通常使用 NSLayoutAnchor 但很多时候我被建议不要使用它。除了更多 complex/longer 代码之外,它是否有任何问题,例如性能下降?

我被告知使用:

let myView = UIView(frame: CGRect(x: 0, y: 20, width: view.frame.bounds.width, height: 100))

而不是:

let myView = UIView()
myView.translatesAutoresizingMaskIntoConstraints = false
myView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
myView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

使用frames缺点是,一旦你把它们布置好,你需要在需要改变的时候手动改变它们相对于某事。例如:方向变化、动画等。但是如果你使用 autolayout,你将相对地定义视图的位置,这意味着,即使在方向变化或动画的情况下,你的视图将根据您设置的约束自行调整大小。

关于性能下降,自动布局需要更多时间(不是那么多)来计算视图的框架,但这可以忽略不计,而且这种便捷方式掩盖了性能影响。

最后,考虑到大多数视图需要根据屏幕尺寸、方向变化等进行某种动态定位这一事实,框架的用例会非常小。混合框架和自动布局是从来都不是个好主意。


Tl;dr - 自动布局 > 框架。

首先,我想确认使用框架比自动布局快得多(据我所知大约是 10 倍)。这就是另一个人告诉您使用框架而不是自动布局的原因。虽然@RakeshaShastri 有一个很好的答案来解释为什么我们应该使用自动布局,但我的答案将讨论何时应该使用框架而不是自动布局。


  • 在视图控制器上显示UIViewUIButtonUILabel...等普通视图时,可以使用自动布局。使用框架和自动布局之间的区别是微不足道的。
  • 对于UICollectionViewCellUITableViewCell,您应该使用框架。在这种情况下,框架和自动布局之间的性能存在很大差异。

让我们看看下面的基准来比较它们。

图片来自LayoutFrameworkBenchmark。它显示了布局 100 个 UICollectionView 单元格时的性能

如您所见,自动布局比手动布局和非自动布局花费更多时间(约 15 倍)。差异会影响 collection 视图在滚动时的平滑度。

特别是当您的单元格具有繁重的视图层次结构时,自动布局将花费大量时间根据具有多余计算的约束来计算单元格子视图的位置。它可以使 collection 视图或 table 视图在滚动时滞后。在这里使用 frame 是为了尽可能减少多余的计算,帮助我们节省其他任务的时间。


结论:

  • UICollectionViewCellUITableViewCell 上使用自动布局时要小心。如果您的 collection 视图或 table 视图在滚动时不流畅,自动布局可能是一个重要原因。

  • 仅当您遇到自动布局问题时才使用框架。在正常情况下使用框架获得的性能是微不足道的。

如果您担心 complex/long 代码,请尝试 SnapKit。它让你爱上自动布局 https://github.com/SnapKit/SnapKit

话虽如此,很多人倾向于认为 AutoLayout VS Frame。但实际上你应该同时使用两者。如果您的视图不会改变并且需要快速交互,请使用框架。如果您希望视图可缩放并处理 landscape/portrait,请使用 AutoLayout。