在下面的代码中,这四种方法用于布局推理。不过,我有点困惑,为什么需要所有这些工具,以及它们之间的不同之处。在这个过程中,它们用于使单元格的高度随着自动布局而动态变化。(摘自此问题的存储库。)
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
这是一段关于细胞高度的代码:
- (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;
}
但是他们有什么不同之处?为什么他们都需要?
假设您将视图逻辑封装在一个子类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.
但你很少需要这样做。在Cocoa Touch的黑暗时代,这种手动布局很普遍,但现在我想说99%的布局可以被自动布局覆盖。
系统需要知道何时应该调用UIView layoutSubviews。显然,这是在您第一次需要绘制视图时完成的,但也可以在superview帧更改时调用它。这里有一个详细的解释。
因此,系统经常调用[查看布局需要]。您也可以随时调用它,但只有当有某个事件调用了[查看setNeedsLayout]或您手动调用它(如本例所示)时,此操作才会生效。
自动布局(在文档中以这种方式大写)之所以这样调用,是因为您将其保留为继承自UIView的视图,并用约束来描述子视图的位置。
使用自动布局时,系统将在每次布局过程中调用[查看更新约束条件(如果需要)]。但是,仅当标志[view setNeedsUpdateConstraints] ,则该方法将调用updateConstraints(执行实际工作)。
如果不使用自动布局,则这些方法不相关。
您可以像本例中那样实现它。
很少需要直接调用layoutIfNeeded和updateConstraintsIfNeeded,因为UI引擎会在每次布局过程中自动执行此操作。然而,在这种情况下,作者选择了立即给他们打电话;这是因为现在需要最终高度,而不是将来某个时候。
这种更新单元格高度的方法似乎是正确的。请注意,单元格可以是新创建的单元格,因此尚未添加到视图层次结构中;这不会影响其自身布局的能力。
在自定义视图中,从最“通用”到最“自定义”的选项如下:
在更改可能导致视图约束更改的内容的代码中,调用
[view setNeedsUpdateConstraints];
如果您需要立即获得结果,请致电
[view updateConstraintsIfNeeded];
如果代码更改视图的框架使用
[view setNeedsLayout];
最后,如果你想立即得到结果,请致电
[view layoutIfNeeded];
这就是为什么在这种情况下需要所有四个调用。
请参阅文章《高级自动布局工具箱》(Advanced Auto Layout Toolbox,objc)中的详细说明。io问题#3
问题内容: 在Go的整个Google App Engine文档中,它们可互换使用库。这是一个例子: 我应该使用哪些库?主要区别是什么? 问题答案: cloud.google.com/go/datastore是Cloud Datastore rest API(可从任何地方使用)的客户端库。 google.golang.org/appengine/datastore是App Engine API的一部
本文向大家介绍图片加载框架有哪些?他们之间的区别是什么?(这个也是必问的)相关面试题,主要包含被问及图片加载框架有哪些?他们之间的区别是什么?(这个也是必问的)时的应答技巧和注意事项,需要的朋友参考一下 ImageLoader : 优点: ① 支持下载进度监听; ② 可以在 View 滚动中暂停图片加载; ③ 默认实现多种内存缓存算法这几个图片缓存都可以配置缓存算法,不过 ImageLoader
问题内容: 我为程序使用了HashMap,它运行良好,但是我不理解HashMap的这些初始化之间的区别。 假设我正在实现一个HashMap,以字符作为键,并以整数作为值。这些有什么区别? 问题答案: 任何涉及或不涉及类型实参的内容(尖括号<和>及其之间的部分)都是原始类型,不应使用。原始类型不是通用类型,可以让您做不安全的事情。 “正确”的方法是 第一种使用接口Map作为参考类型。它通常比较惯用,
从文档,关于
本文向大家介绍Kafka和Flume之间的主要区别是什么?相关面试题,主要包含被问及Kafka和Flume之间的主要区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 答:Kafka和Flume之间的主要区别是: 工具类型 Apache Kafka——Kafka是面向多个生产商和消费者的通用工具。 Apache Flume——Flume被认为是特定应用程序的专用工具。 复制功能 Apache
问题内容: 网上似乎充满了Velocity和FreeMarker之间的比较,并且它们似乎相当等效。但是,StringTemplate和FreeMarker之间似乎几乎没有比较! 那么,StringTemplate和FreeMarker之间的主要区别是什么? 我对它们的用法是仅生成HTML页面。在这两种方法中,我曾期望FreeMarker更合适,功能更强大,因为这似乎是更常见的一种- 但快速浏览一下