UILabel 的 preferredMaxLayoutWidth 属性研究
来源:互联网 发布:动漫周边淘宝 编辑:程序博客网 时间:2024/06/13 00:44
下面这张图对于有强迫症的 iOS 开发应该并不陌生,只要 xib 中将 UILabel 的 numberOfLines 设置为非 1(0或2,3…)并且没有在 xib 中设置 preferredMaxLayoutWidth 就会出现该警告。
消除该警告,有两种比较常见的方法
- 在 xib 中把相应 Label 的 numberOfLines 先设置为 1,再到代码中初始化的地方设置 numberOfLines 为自己想要的非 1 值。
- 在 xib 中把相应 Label 的 preferredMaxLayoutWidth 设置为 0,如下图所示:
那么问题来了,上面第二中方法把 preferredMaxLayoutWidth 设置为 0 会不会有什么影响呢?
- 首先看下苹果文档中对 UILabel 的 preferredMaxLayoutWidth 属性的说明
- 于是自己创建了测试工程看下这个属性具体会影响到哪些地方
- 1.对于 numberOfLines 为 1 的 UILabel,根据上面的文档说明这个属性没有什么作用。
- 2.对于 numberOfLines 为非 1(0或2,3…)的 UILabel,下面再细分两种情况:
- (1).如果 xib 中没有足够的约束确定 UILabel 的宽度,则会用 preferredMaxLayoutWidth 决定其最大的隐式宽度,文字内容不足 preferredMaxLayoutWidth 宽度,则隐式宽度约束为文字所需的宽度;如果超过 preferredMaxLayoutWidth 宽度则会换行(注意一下,如果 preferredMaxLayoutWidth 为 0 则永远不会换行)。调用其父视图(或者父视图的父视图)的 [superView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] 方法计算其父视图最小宽高时,就会用 preferredMaxLayoutWidth 作为换行宽度计算其中的 numberOfLines 非 1 的 UILabel 需要的高度(正常的换行符也会马上换行)(注意一下,如果 preferredMaxLayoutWidth 为 0 则永远不会换行,需要的高度就是一行需要的高度),然后一层层根据相对约束确定 superView 需要的最小宽高。对 UILabel 的 sizeThatFits: 方法没有任何影响。
- (2).如果 xib 中已经有足够的约束确定 UILabel 的宽度,则不会再用 preferredMaxLayoutWidth preferredMaxLayoutWidth 决定换行,而是用约束确定的宽度去决定换行(如果 preferredMaxLayoutWidth 为 0 则更不会影响)。调用其父视图(或者父视图的父视图)的 [superView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] 方法计算其父视图最小宽高时,依然会使用 preferredMaxLayoutWidth 作为换行宽度计算其中的 numberOfLines 非 1 的 UILabel 需要的高度(正常的换行符也会马上换行)(注意一下,如果 preferredMaxLayoutWidth 为 0 则继续用约束确定的宽度作为换行换行宽度计算所需高度),然后一层层根据相对约束确定 superView 需要的最小宽高。对 UILabel 的 sizeThatFits: 方法没有任何影响。
经过研究,暂时没有发现上面的第二种修改方法(xib 把 preferredMaxLayoutWidth 设置为 0)会产生什么不好的影响。
但是把 preferredMaxLayoutWidth 设置为非 0 对于上面的2-(2)里面的情况就有非常大的影响了,我们常用的 UITableView+FDTemplateLayoutCell 动态计算 Cell 高度中就用了 systemLayoutSizeFittingSize: 方法。
最后贴一段 UITableView+FDTemplateLayoutCell 中先用 systemLayoutSizeFittingSize: 方法计算高度的代码。
if (!cell.fd_enforceFrameLayout && contentViewWidth > 0) { // Add a hard width constraint to make dynamic content views (like labels) expand vertically instead // of growing horizontally, in a flow-layout manner. NSLayoutConstraint *widthFenceConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:contentViewWidth]; // [bug fix] after iOS 10.3, Auto Layout engine will add an additional 0 width constraint onto cell's content view, to avoid that, we add constraints to content view's left, right, top and bottom. static BOOL isSystemVersionEqualOrGreaterThen10_2 = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ isSystemVersionEqualOrGreaterThen10_2 = [UIDevice.currentDevice.systemVersion compare:@"10.2" options:NSNumericSearch] != NSOrderedAscending; }); NSArray<NSLayoutConstraint *> *edgeConstraints; if (isSystemVersionEqualOrGreaterThen10_2) { // To avoid confilicts, make width constraint softer than required (1000) widthFenceConstraint.priority = UILayoutPriorityRequired - 1; // Build edge constraints NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeRight multiplier:1.0 constant:accessroyWidth]; NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; edgeConstraints = @[leftConstraint, rightConstraint, topConstraint, bottomConstraint]; [cell addConstraints:edgeConstraints]; } [cell.contentView addConstraint:widthFenceConstraint]; // Auto layout engine does its math fittingHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; // Clean-ups [cell.contentView removeConstraint:widthFenceConstraint]; if (isSystemVersionEqualOrGreaterThen10_2) { [cell removeConstraints:edgeConstraints]; } [self fd_debugLog:[NSString stringWithFormat:@"calculate using system fitting size (AutoLayout) - %@", @(fittingHeight)]]; }
阅读全文
0 0
- UILabel 的 preferredMaxLayoutWidth 属性研究
- autolayout 动态计算高度时 UILabel的preferredMaxLayoutWidth设置
- autolayout 动态计算高度时 UILabel的preferredMaxLayoutWidth设置
- preferredMaxLayoutWidth
- UILabel 的深入研究
- UILabel的属性
- UILabel的各种属性
- UILabel 的属性
- UILabel的属性总结
- UILabel的常用属性
- UILabel的各种属性
- iphone UILabel的属性应用
- UiLabel的属性和用法
- UILabel的属性和方法
- UILabel的相关属性设置
- UILabel的常用属性介绍
- UILabel和UIButton的属性
- UILabel的相关属性设置
- ubuntu16.04安装pycharm,codelite,bluefish
- 【ASP.NET】 传递数据为空
- nginx 优化(突破十万并发)
- 进程间通信--共享内存
- connect-history-api-fallback node开发之
- UILabel 的 preferredMaxLayoutWidth 属性研究
- Linux内核和用户空间通信的方式(一)— proc文件和mmap共享内存
- Socket通信——Linux下,errno=EINTR的错误处理
- latex 中加入参考文献方法
- javaWeb项目的classpath说明
- 0x3f3f3f3f知多少
- node开发之Formidable
- Py
- 6.13作业:数据类型及包的定义作用以及JAVA类的封装,表达式,标识符