简体   繁体   English

所有这些自动布局更新方法有什么区别? 都有必要吗?

[英]What is the difference between all these Auto Layout update methods? Are all necessary?

In the code below, these four methods are called for layout reasoning. 在下面的代码中,调用这四种方法进行布局推理。 I'm a little confused why all of them are needed, though, and what they do differently from one another. 我有点困惑为什么所有这些都是需要的,以及它们彼此不同的做法。 They're used in the process to make a cell's height be dynamic with Auto Layout. 它们在过程中用于通过自动布局使单元格的高度变为动态。 (Taken from this repository from this question .) (摘自此问题的 存储库 。)

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];

And it's from this block of code for the cell's height: 它来自这个单元格高度的代码块:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    RJTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    [cell updateFonts];

    NSDictionary *dataSourceItem = [self.model.dataSource objectAtIndex:indexPath.row];
    cell.titleLabel.text =  [dataSourceItem valueForKey:@"title"];
    cell.bodyLabel.text = [dataSourceItem valueForKey:@"body"];

    cell.bodyLabel.preferredMaxLayoutWidth = tableView.bounds.size.width - (kLabelHorizontalInsets * 2.0f);

    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];
    [cell.contentView setNeedsLayout];
    [cell.contentView layoutIfNeeded];

    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    return height;
}

But what are they doing differently? 但他们的做法有何不同? Why are they all needed? 他们为什么都需要?

Layout 布局

Suppose you encapsulate your view logic in a UIView subclass, and call it SomeView . 假设您将视图逻辑封装在UIView子类中,并将其SomeView This means that SomeView should know how to layout itself, that is, how to position some other views inside it (you can also create a view that draws itself without using any subviews, but that's beyond the needs of an average developer). 这意味着SomeView应该知道如何布局自己,也就是说,如何在其中放置一些其他视图(您还可以创建一个不使用任何子视图绘制自己的视图,但这超出了普通开发人员的需求)。

This layout is done by [SomeView layoutSubviews] . 此布局由[SomeView layoutSubviews] You have an option of overriding it: 您可以选择覆盖它:

subview.frame = CGRectMake(100 + shiftX, 50 + shiftY, 250 + shiftX - paddingRight, ...
// Oh no, I think I didn't do it right.

but you rarely need to do so. 但你很少需要这样做。 In the dark ages of Cocoa Touch, this manual layout was widespread, but now I'd say 99% of layouts can be covered with Auto Layout. 在Cocoa Touch的黑暗时代,这种手动布局很普遍,但现在我要说99%的布局可以用自动布局来覆盖。

The system needs to know when it should call [UIView layoutSubviews] . 系统需要知道何时应该调用[UIView layoutSubviews] It's obviously done the first time you need to draw a view, but it may be also called whenever the superview frame changes. 它显然是在您第一次需要绘制视图时完成的,但是每当超视图帧发生变化时也可以调用它。 Here's a detailed explanation . 这是一个详细的解释

So the system often calls [view layoutIfNeeded] . 所以系统经常调用[view layoutIfNeeded] You can also call it at any time, but this will have an effect only if there is some event that has called [view setNeedsLayout] or if you have called it manually, as in this case. 也可以随时调用它,但只有在某个事件调用了[view setNeedsLayout]或者您手动调用它时才会产生效果,就像在这种情况下一样。

Constraints 约束

The Auto Layout (capitalized this way in the documentation ) is called like that because you're leaving [SomeView layoutSubviews] as it is inherited from UIView and describe the position of your subviews instead in terms of constraints . 自动布局 (在文档这种方式大写)就像这样被调用,因为你离开了[SomeView layoutSubviews]因为它是从UIView继承的,并且在约束条件下描述子视图的位置。

When using Auto Layout, system will perform calls to [view updateConstraintsIfNeeded] at each layout pass. 使用自动布局时,系统将在每个布局过程中执行对[view updateConstraintsIfNeeded]调用。 However, only if the flag [view setNeedsUpdateConstraints]; 但是,只有标志[view setNeedsUpdateConstraints]; is set, the method calls into -updateConstraints (which does the real job). 设置后,该方法调用-updateConstraints (完成实际工作)。

If you don't use Auto Layout, those methods are not relevant. 如果您不使用自动布局,则这些方法不相关。

You can implement it like in this example . 您可以像在此示例中一样实现它。

Your example 你的榜样

It's rarely necessary to call -layoutIfNeeded and -updateConstraintsIfNeeded directly, because UI engine will do that automatically at each layout pass. 这是很少需要调用-layoutIfNeeded-updateConstraintsIfNeeded直接,因为UI引擎将在每个布局通自动做到这一点。 However, in this case the author has chosen to call them immediately; 但是,在这种情况下,作者选择立即打电话给他们; this is because the resulting height is needed right now, not at some point in the future. 这是因为现在需要产生的高度,而不是将来的某个时刻。

This method of updating the cell's height seems right. 这种更新细胞高度的方法似乎是正确的。 Note that cell could be a newly created cell and thus not added into view hierarchy yet; 请注意, cell可能是新创建的单元格,因此尚未添加到视图层次结构中; this does not impact its ability to layout itself. 这不会影响其布局本身的能力。

Conclusion 结论

In your custom view go with the following options, starting from the most 'universal' to most 'customized': 在自定义视图中,请使用以下选项,从最“通用”到“大多数”自定义:

  1. Create constraints during view creation (manually or in the IB) 在视图创建期间创建约束(手动或在IB中)
  2. If you need to change the constraints later, override -updateConstraints . 如果以后需要更改约束,请覆盖-updateConstraints
  3. If have a complex layout that cannot be described by above means, override -layoutSubviews . 如果具有无法通过上述方式描述的复杂布局,请覆盖-layoutSubviews

In the code that changes something that could make your view's constraints change, call 在更改可能使视图约束发生变化的代码中,请调用

[view setNeedsUpdateConstraints];

If you need results immediately, call also 如果您需要立即获得结果,请致电

[view updateConstraintsIfNeeded]; 

If the code changes view's frame use 如果代码更改视图的框架使用

[view setNeedsLayout]; 

and finally if you want the results immediately, call 最后,如果你想立即得到结果,请致电

[view layoutIfNeeded];

This is why all four calls are required in this case. 这就是为什么在这种情况下需要所有四个呼叫的原因。

Additional materials 其他材料

Take a look at detailed explanation in the article Advanced Auto Layout Toolbox , objc.io issue #3 请查看高级自动布局工具箱文章中的详细说明objc.io问题#3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Xcode中部署的所有4种方法之间有什么区别? - What's the difference between all 4 methods for deployment in Xcode? glkView和update方法有什么区别? - What is the difference between glkView and update methods? iOS中自动布局和自动调整大小的基本区别是什么 - What is the basic difference between Auto Layout and Auto Resizing in iOS 所有选择区段之间有什么区别? - What's the difference between all the Selection Segues? 自动布局所有设备的UIImage - Auto layout a UIImage for all devices UIStackView 和 Auto Layout Anchor 的区别 - Difference between UIStackView and Auto Layout Anchor 如果控制器符合协议,那么它是否有必要为所有协议方法提供一个主体? - If a controller conforms to a protocol then is it necessary for it to provide a body to all the methods of protocol? 以编程方式自动布局:更新视图的垂直空间以移动所有内部视图 - Auto Layout programmatically: Update view's vertical space moving all inner views 使用“自动布局”更新集合视图高度以适合表视图单元格中的所有单元格 - Update collection view height to fit all cells within a table view cell using Auto Layout 自动布局和viewAnimation有什么关系? - What is the relation between auto-layout and viewAnimation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM