我有一个使用 Autolayout 和 iOS8 Dynamic Height 的自定义 UITableViewCell ,包含两个不同大小的标签。上标签可以是 1 到 2 行 的任意位置,而下标签总是只有 1 行。
在 :cellForRowAtIndexPath: 中,我将上部标签的文本设置为“Loading..”并调用一个方法从服务器(或缓存)(可能是任何长度)。第二个标签设置为它的最终文本。
...
cell.title.text = @"Loading...";
cell.subtitle.text = source.name;
__weak NewsTableViewCell *weakCell = cell;
[[NewsManager sharedManager] getNewsForSource:source withBlock:^(NewsObject *object, NSError *error) {
NewsTableViewCell *strongCell = weakCell;
strongCell.title.text = object.articleHeadline;
}];
...
当方法返回并将文本从“正在加载...”更改为实际文本时,会发生以下三种情况之一:
- 一切都正确呈现。
- 第二个标签被移除,第一个标签被固定到一行。
- 第一个标签在一半宽度处被切断(这通常发生在将手机侧向并再次恢复为纵向后)。
我在 viewWillAppear: 中调用 [self.tableView reloadData] ,所以如果出现错误渲染,只需打开另一个 View 并返回此即可解决问题。 Handlebars 机翻到另一边也是如此,然后又变回原来的样子。
这是一张解释发生了什么的图片(注意:两个单元格都应该像第二个单元格):
以下是我在 StoryBoard 中使用 AutoLayout 设置 UITableViewCell 的方法:
我没有更改任何属性(如拥抱和压缩优先级)。
谁能指导我正确的方向/让我知道我做错了什么?
编辑 1: 这是一张显示不同 UILabel Frames 的照片(1)正确的布局(2)错误的布局( 3) 单元格等待其最终文本时的布局(这会导致出现错误的布局)
编辑 2: 从 block 中调用 [strongCell setNeedsLayout] 和 [strongCell layoutIfNeeded] 不能解决我的问题,但会导致此 AutoLayout 错误会出现在控制台中。你能帮我调试一下吗?
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you
don't want. Try this: (1) look at each constraint and try to figure out which
you don't expect; (2) find the code that added the unwanted constraint or
constraints and fix it. (Note: If you're seeing
NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the
documentation for the UIView property
translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x1700927a0 UILabel:0x127d39c20'Horrifying moment lioness...'.top == UITableViewCellContentView:0x127d2e510.topMargin>",
"<NSLayoutConstraint:0x170092930 V:[UILabel:0x127d39c20'Horrifying moment lioness...']-(8)-[UILabel:0x127d39dd0'Daily Mail Online']>",
"<NSLayoutConstraint:0x170092a70 UILabel:0x127d39dd0'Daily Mail Online'.bottom == UITableViewCellContentView:0x127d2e510.bottomMargin>",
"<NSLayoutConstraint:0x170092c00 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x127d2e510(0)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170092930 V:[UILabel:0x127d39c20'Horrifying moment lioness...']-(8)-[UILabel:0x127d39dd0'Daily Mail Online']>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Best Answer-推荐答案 strong>
为了使单元格重新布局,您需要使用 reload 方法reload 单元格。
你可以通过这种方式实现它...
首先,创建一个可变字典属性来存储单元格的文本...
@property (nonatomic, strong) NSMutableDictionary *textDictionary;
然后在某处初始化它。
然后在单元格中换行...
更新了以下评论
- (UITableViewCell *)tableViewUITableView *)tableView cellForRowAtIndexPathNSIndexPath *)indexPath
{
...
cell.subtitle.text = source.name;
// get the text from the dictionary
NSString *titleText = self.textDictionary[source];
if (titleText) {
// second time through the text exists so just use it.
cell.title.text = titleText;
} else {
// first time through the text is nil so set it to default and download it.
cell.title.text = @"Loading...";
// this just stops the download starting again before it has completed
self.textDictionary[source] = @"Loading...";
}
// recheck the text and reload if it has changed
[[NewsManager sharedManager] getNewsForSource:source withBlock:^(NewsObject *object, NSError *error) {
NSString *oldText = self.textDictionary[source];
NSString *newText = object.articleHeadline;
// reload if the text has changed
if (![oldText isEqualToString:newText]) {
// store the text in the dictionary
self.textDictionary[source] = newText;
// reload the indexPath (will only trigger if the cell is visible)
[tableView reloadRowsAtIndexPaths[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}];
....
}
第一次通过这个触发字符串的异步获取。完成后,它将其存储在本地,然后重新加载该行。
第二次通过它只会获取本地存储的字符串并使用它而无需再次下载。
关于ios - 文本更改时自动布局动态高度 TableView 单元格呈现错误,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/30684220/
|