Dou*_*ith 28 objective-c uiview ios autolayout nslayoutconstraint
在下面的代码中,调用这四种方法进行布局推理.我有点困惑为什么所有这些都是需要的,以及它们彼此不同的做法.它们在过程中用于通过自动布局使单元格的高度变为动态.(来自该库从这个问题.)
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)
它来自这个单元格高度的代码块:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
但他们的做法有何不同?他们为什么都需要?
ily*_* n. 45
假设您将视图逻辑封装在UIView子类中,并调用它SomeView.这意味着SomeView应该知道如何布局自己,也就是说,如何在其中放置一些其他视图(您还可以创建一个不使用任何子视图绘制自己的视图,但这超出了普通开发人员的需求).
这种布局是通过[SomeView layoutSubviews].您可以选择覆盖它:
subview.frame = CGRectMake(100 + shiftX, 50 + shiftY, 250 + shiftX - paddingRight, ...
// Oh no, I think I didn't do it right.
Run Code Online (Sandbox Code Playgroud)
但你很少需要这样做.在Cocoa Touch的黑暗时代,这种手动布局很普遍,但现在我要说99%的布局可以用自动布局来覆盖.
系统需要知道何时应该呼叫[UIView layoutSubviews].它显然是在您第一次需要绘制视图时完成的,但是每当超视图帧发生变化时也可以调用它.这是一个详细的解释.
所以系统经常打电话[view layoutIfNeeded].您也可以随时调用它,但只有当某个事件已经调用[view setNeedsLayout]或者您手动调用它时才会产生效果,就像在这种情况下一样.
该自动布局(大写这种方式中的文档),因为你要离开了被称为这样的[SomeView layoutSubviews],因为它是从继承UIView和描述,而不是表示你的子视图的位置约束.
使用自动布局时,系统将[view updateConstraintsIfNeeded]在每个布局过程中执行调用.但是,只有[view setNeedsUpdateConstraints];设置了标志,方法-updateConstraints才会调用(执行实际工作).
如果您不使用自动布局,则这些方法不相关.
您可以像在此示例中一样实现它.
这是很少需要调用 -layoutIfNeeded和-updateConstraintsIfNeeded直接,因为UI引擎将在每个布局传球被自动执行.但是,在这种情况下,作者选择立即打电话给他们; 这是因为现在需要产生的高度,而不是将来的某个时刻.
这种更新细胞高度的方法似乎是正确的.请注意,这cell可能是新创建的单元格,因此尚未添加到视图层次结构中; 这不会影响其布局本身的能力.
在自定义视图中,请使用以下选项,从最"通用"到"大多数"自定义:
-updateConstraints.-layoutSubviews.在更改可能使视图约束发生变化的代码中,请调用
[view setNeedsUpdateConstraints];
Run Code Online (Sandbox Code Playgroud)
如果您需要立即获得结果,请致电
[view updateConstraintsIfNeeded];
Run Code Online (Sandbox Code Playgroud)
如果代码更改视图的框架使用
[view setNeedsLayout];
Run Code Online (Sandbox Code Playgroud)
最后,如果你想立即得到结果,请致电
[view layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)
这就是为什么在这种情况下需要所有四个呼叫的原因.
请查看高级自动布局工具箱文章中的详细说明,objc.io问题#3
| 归档时间: |
|
| 查看次数: |
9576 次 |
| 最近记录: |