我有一个带有自定义单元格的表视图(所有单元格都使用自动布局在子类中配置)。
单元格加载正常,显示正常,一切正常。
问题是当我在底部插入更多行时。表格视图代表帖子的供稿,因此当用户滚动到底部时,在到达最后一个单元格之前,我加载了新帖子,然后将它们插入表格中。
当我这样做时,我得到了这种奇怪的毛刺效果,即单元格随机下降(位于前一个单元格之后)到位,表格视图向上滚动,有点混乱。
我上传了一个我正在滚动的剪辑。当您看到活动指示器时, 我停止滚动。运动的其余部分来自故障行为。
我不希望,但是idk ..我不确定该怎么做。如果有人有任何想法,请告诉我。
仅供参考:
我有这个(当然,因为所有单元格都使用自动布局)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
我尝试将估计高度设置为预期单元格高度的“平均值”,约为65。没有区别。
以下是一些代码:
HomeViewController.m -> viewDidLoad
...
self.tableView = [KATableView.alloc initWithFrame:CGRectZero style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.refreshDelegate = self;
self.tableView.estimatedRowHeight = 75;
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.view addSubview:self.tableView];
// Constrains to all 4 sides of self.view
[SSLayerEffects constrainView:self.tableView toAllSidesOfView:self.view];
我的表格视图数据源
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (!self.dataManager.didFinishFetchingData) return 4;
if (self.contentObjects.count == 0) return 1;
if (self.dataManager.moreToLoad) return self.contentObjects.count + 1;
return self.contentObjects.count + 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MYObject *object = self.contentObjects[indexPath.row];
SomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:object.documentID];
if (!cell) {
cell = [SomeTableViewCell.alloc initWithStyle:UITableViewCellStyleDefault reuseIdentifier:object.documentID];
cell.delegate = self;
} else [cell startListeningForChanges];
return cell;
}
这是我加载更多数据并将其添加到表格视图中的方式。
- (void)getHomeFeedData:(nullable void(^)(BOOL finished))completed {
[self.dataManager fetchHomeFeedDataForFeedOption:self.homeNavController.feedFilterOption completion:^(NSError * _Nullable error, NSArray<__kindof KAObject *> * _Nullable feedObjects) {
if (error != nil) {
NSLog(@"something went wrong: %@", error.localizedDescription);
if (completed) completed(NO);
return;
}
NSInteger originalCount = self.contentObjects.count;
if (self.dataManager.isFirstTimeLoading) self.contentObjects = feedObjects.mutableCopy;
else {
if (self.dataManager.isGettingNew) for (MYObject *obj in feedObjects) [self.contentObjects insertObject:obj atIndex:0];
else if (feedObjects.count > 0) [self.contentObjects addObjectsFromArray:feedObjects];
}
if (feedObjects.count > 0) {
if (self.dataManager.isFirstTimeLoading) [self.tableView reloadData];
else {
[self.tableView insertCells:feedObjects forSection:0 startingIndex:self.dataManager.isGettingNew? 0 : originalCount];
}
} else if (self.dataManager.isFirstTimeLoading) [self.tableView reloadData];
if (completed) completed(YES);
}];
}
注意:
[self.tableView insertCells:feedObjects forSection:0 startingIndex:self.dataManager.isGettingNew? 0 : originalCount];
就是这样:
- (void)insertCells:(nullable NSArray *)cells forSection:(NSInteger)section startingIndex:(NSInteger)start {
if (!cells) return;
NSMutableArray *indexPaths = @[].mutableCopy;
for (id obj in cells) {
NSInteger index = [cells indexOfObject:obj] + start;
[indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:section]];
}
[self insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
我的UITableViewCell
子类内容是隐藏的ATM(出于发布此帖子的目的,编辑我的所有帖子内容太困难了)。我只是将每个单元格的子视图设置为alpha = 0.f
。它只是一个图像视图,一些标签和一些按钮。
控制台中没有约束问题,调用[self.tableView reloadData]
时单元格呈现完美,所以也许在插入单元格时我做错了什么......
答案 0 :(得分:1)
处理UITableView
的故障时:
对于您而言,可能存在一个问题,即fetchHomeFeedDataForFeedOption:completion:
完成块不在主线程上调用。
您的插入内容绝对是错误的-对UITableView
的所有删除/插入/更新/移动调用均应包装在beginUpdates
/ endUpdates
您底部的“加载更多”组件可能是一个问题。您需要解决它如何管理表视图的contentSize / contentOffset / contentInset。如果除了操作contentInset以外,它什么都没做-它做错了工作。
尽管很难调试整个解决方案,但我敢肯定选项2和3是关键问题。