我正在尝试学习自动布局,最后我想在发生这种情况时我正在 grab 它 . 我正在玩原型细胞和标签 . 我想要一个
-
Headers ,
titleLbl
- 图片中的蓝框 -
Money,
moneyLbl
- 图片中的绿框 -
字幕/描述,
subTitleLbl
- 图片中的红框
到目前为止我有这个:
我想要实现的是:
-
绿框应始终完全显示在1行
-
绿框内的值应基于蓝框居中
-
蓝色框将占用剩余空间(-8px表示2之间的水平约束)并在必要时显示多行
-
红色框应位于下方,并根据需要显示尽可能多的行 .
正如您所看到的,除了最后一行中的示例之外,这几乎都可以正常工作 . 我试图对此进行研究,从我可以收集的内容来看,这与内在的内容大小有关 . 很多在线帖子都建议设置 setPreferredMaxLayoutWidth
,我已经在 titleLbl
的多个地方完成了这个并且它没有任何效果 . 只有在将其硬编码到 180
时才能得到结果,但它还在文本顶部/下方的其他蓝框中添加了空格/填充,大大增加了红/蓝框之间的空间 .
这是我的约束:
Headers :
钱:
副 Headers :
基于我与其他文本样本一起运行的测试,它看起来确实使用了故事板中显示的宽度,但任何纠正它的尝试都不起作用 .
我创建了一个单元格的ivar并用它来创建单元格的高度:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[sizingCellTitleSubMoney.titleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"title"]];
[sizingCellTitleSubMoney.subtitleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"subtitle"]];
[sizingCellTitleSubMoney.moneyLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"cost"]];
[sizingCellTitleSubMoney layoutIfNeeded];
CGSize size = [sizingCellTitleSubMoney.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height+1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MATitleSubtitleMoneyTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifierTitleSubTitleMoney];
if(!cell)
{
cell = [[MATitleSubtitleMoneyTableViewCell alloc] init];
}
cell.titleLbl.layer.borderColor = [UIColor blueColor].CGColor;
cell.titleLbl.layer.borderWidth = 1;
cell.subtitleLbl.layer.borderColor = [UIColor redColor].CGColor;
cell.subtitleLbl.layer.borderWidth = 1;
cell.moneyLbl.layer.borderColor = [UIColor greenColor].CGColor;
cell.moneyLbl.layer.borderWidth = 1;
[cell.titleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"title"]];
[cell.subtitleLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"subtitle"]];
[cell.moneyLbl setText:[[tableViewData objectAtIndex:indexPath.row] objectForKey:@"cost"]];
return cell;
}
我已经尝试在单元格的布局子视图中设置 setPreferredMaxLayoutWidth
:
- (void)layoutSubviews
{
[super layoutSubviews];
NSLog(@"Money lbl: %@", NSStringFromCGRect(self.moneyLbl.frame));
NSLog(@"prefferredMaxSize: %f \n\n", self.moneyLbl.frame.origin.x-8);
[self.titleLbl setPreferredMaxLayoutWidth: self.moneyLbl.frame.origin.x-8];
}
日志:
2014-04-30 21:37:32.475 AutoLayoutTestBed[652:60b] Money lbl: {{209, 20}, {91, 61}}
2014-04-30 21:37:32.475 AutoLayoutTestBed[652:60b] prefferredMaxSize: 201.000000
这是我所期望的,因为2个元素之间有8px,控制台验证了这一点 . 无论我在蓝色框中添加多少文本(与故事板相同),它在第一行上都能完美运行,但绿色框的任何增加都会导致宽度计算失败 . 我已经尝试在 tableView:willDisplayCell
和 tableView:heightForRowAtIndexPath:
中根据其他问题的答案设置此项 . 但不管它只是没有布局 .
任何帮助,想法或意见将不胜感激
4 回答
阅读本文后找到了更好的答案:http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights
创建一个
UILabel
子类来覆盖layoutSubviews
,如下所示:这可确保
preferredMaxLayoutWidth
始终正确 .Update:
经过几次释放后,我发现上述情况并不适合每一个案例 . 从iOS 8开始(我相信),在某些情况下,只有在屏幕加载之前及时调用
didSet
bounds
.在最近的iOS 9中,当使用带有
UITableView
的模态UIVIewController
时,我遇到了另一个问题,即layoutSubviews
和set bounds
被称为 afterheightForRowAtIndexPath
. 经过多次调试后,唯一的解决方案是覆盖set frame
.以下代码现在似乎是必要的,以确保它适用于所有iOS,控制器,屏幕尺寸等 .
我不确定我理解你是对的,我的解决方案与最好的解决方案相差甚远,但这里是:
我在已切割的标签上添加了一个高度约束,将该约束连接到单元的出口 . 我已经覆盖了layoutSubview方法:
和中提琴!请尝试该方法并告诉我结果,谢谢 .
我确实花了一些时间来整理细胞,看起来像这样:
经过多次尝试,我做了一个解决方案,如何使用实际工作的原型单元 .
主要的麻烦是我的标签可能或可能不存在 . 每个元素都应该是可选的 .
首先,我们的“原型”单元格应该只在我们不处于“真实”环境时布局 .
因此,我确实创建了标志'heightCalculationInProgress' .
当有人(tableView的dataSource)要求计算高度时,我们使用块向原型单元格提供数据:然后我们要求我们的原型单元格布置内容并从中获取高度 . 简单 .
为了避免iOS7与layoutSubview递归的错误,有一个“layoutingLock”变量
来自外部的“阻止”可能如下所示:
现在开始最有趣的部分 . 布点:
哦,只是有同样的问题 . @Simon McLoughlin的回答对我没有帮助 . 但
做了一个魔术!它有效,我不知道为什么,但确实如此 . 和是的,您的标签必须具有明确的preferredMaxLayoutWidth值 .