我有UITableViewCell
,其中包含带有自动布局的TWTRTweetView
。我正在加载这样的推文:
- (void)loadTweetWithId:(NSString *)tweetId {
if (mTweetId == nil || ![mTweetId isEqualToString:tweetId]) {
mTweetId = tweetId;
[[[TWTRAPIClient alloc] init] loadTweetWithID:tweetId completion:^(TWTRTweet *tweet, NSError *error) {
if (tweet) {
NSLog(@"Tweet loaded!");
[mTweetView configureWithTweet:tweet];
[mTweetView setShowActionButtons:YES];
//[mTweetView setDelegate:self];
[mTweetView setPresenterViewController:self.viewController];
[mTweetView setNeedsLayout];
[mTweetView layoutIfNeeded];
[mTweetView layoutSubviews];
hc.constant = mTweetView.frame.size.height;
[self updateConstraints];
[self layoutIfNeeded];
[self layoutSubviews];
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
[self.tableView layoutSubviews];
} else {
NSLog(@"Tweet load error: %@", [error localizedDescription]);
}
}];
}
}
当推文加载的单元格没有调整大小时,除非我将其向外滚动并将其向后滚动。我已经尝试了几种方法,你可以在代码片段中看到。但不是这些作品。我的表格视图使用全自动布局方法,该方法不会为行功能实现单元格高度。我该如何解决这个问题?
更新
使用:
[self.tableView beginUpdates];
[self.tableView endUpdates];
是不可能的,因为当我这样做时,所有细胞都被重新绘制并且发生非常大的跳跃并且这是不可接受的。我也确认推文完成块在主线程中运行。
更新2:
我还尝试使用tweet id缓存tweet视图并重新加载相关索引路径的单元格,并为tweet id提供相同的tweet视图。单元格高度已更正,但在向外滚动之前不会显示。
更新3:
我在单元格的xib中为tweet视图提供约束,并且连接了高度约束。所以这不是一个主要的线程问题。我还提到在索引处重新加载特定单元格并不起作用。
在使用其他解决方案时,我看到了一些使用TwitterKit
的示例TWTRTweetTableViewCell
代码但正在预加载推文以配置单元格。所以我也做了同样的事情。这当然是一种解决方法。
答案 0 :(得分:0)
在使用
加载推文后尝试重新加载该特定单元格- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
withRowAnimation:(UITableViewRowAnimation)animation;
答案 1 :(得分:0)
我有类似的问题,我通过在dispatch_async中添加所有代码来确保它在主线程上运行,从而解决了这个问题。
dispatch_async(dispatch_get_main_queue(), ^{
/*CODE HERE*/
});
所以你的代码应该是这样的:
- (void)loadTweetWithId:(NSString *)tweetId {
if (mTweetId == nil || ![mTweetId isEqualToString:tweetId]) {
mTweetId = tweetId;
[[[TWTRAPIClient alloc] init] loadTweetWithID:tweetId completion:^(TWTRTweet *tweet, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (tweet) {
NSLog(@"Tweet loaded!");
[mTweetView configureWithTweet:tweet];
[mTweetView setShowActionButtons:YES];
//[mTweetView setDelegate:self];
[mTweetView setPresenterViewController:self.viewController];
[mTweetView setNeedsLayout];
[mTweetView layoutIfNeeded];
[mTweetView layoutSubviews];
hc.constant = mTweetView.frame.size.height;
[self updateConstraints];
[self layoutIfNeeded];
[self layoutSubviews];
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
[self.tableView layoutSubviews];
} else {
NSLog(@"Tweet load error: %@", [error localizedDescription]);
}
});
}];
}
}
答案 2 :(得分:0)
你做错了一些可能导致(或至少有助于)跳跃的事情:
永远不要自己致电layoutSubviews
。
它是系统调用以解决约束的方法。在连续拨打setNeedsLayout
和layoutIfNeeded
时会自动触发。
这同样适用于updateConstraints
。系统在布局过程中调用它。您可以随后调用setNeedsUpdateContraints
和updateConstraintsIfNeeded
来手动触发它。此外,只有在自定义视图(或单元格)中实际实现(覆盖)该方法时才会产生影响。
当您在视图上调用layoutIfNeeded
时,它会布置其子视图。因此,当您更改约束mTweetView
的约束的常量时,它可能不会产生任何效果(除非在触发的布局传递期间视图层次结构无效)。您需要在layoutIfNeeded
的超级视图上调用mTweetView
,这是该单元格的内容视图(根据您添加到帖子中的屏幕截图判断):
[contentView layoutIfNeeded];
此外,还有一件事需要注意,这也可能导致闪烁:
prepareForReuse
方法)。请确保您已修复所有这些问题,并查看动画现在是否按预期工作。 (我在下面的原始答案仍然有效。)
我很确定
[self.tableView beginUpdates];
[self.tableView endUpdates];
唯一的方法让细胞在显示时自动调整大小。
对于历史性的和性能原因,UITableView
始终适用于固定高度的单元格(内部)。即使通过设置estimatedRowHeight
等使用自调整单元格,表格视图也会计算单元格出列时的高度,即之前它出现在屏幕上。然后,它会向单元格添加一些内部约束,使其具有固定宽度和固定高度,它与自动布局计算的大小相匹配。
这些内部约束仅在需要时更新,即重新加载行时。现在当你在你的单元格中添加任何约束时,你将会&#34;战斗&#34;针对具有必需优先级(又称1000)的内部约束。换句话说:没有办法获胜!
更新这些内部(固定)单元格约束的唯一方法是告诉表视图它应该。据我所知,唯一公开(记录)的API是
- (void)beginUpdates;
- (void)endUpdates;
所以剩下的唯一问题是:
我认为在重新调整单元格之后重新绘制单元格是合法的。展开单元格以显示比在需要之前重新绘制单元格之前更长的推文!
您可能不会(并且不应该)始终调整所有可见单元格。 (这对用户来说会很混乱......)