[英]UITableView Cell Insert Row Glitch
我有一個帶有自定義單元格的表視圖(所有單元格都使用自動布局在子類中配置)。
單元格加載正常,顯示正常,一切正常。
問題是當我插入更多行時(在底部)。 表格視圖代表帖子的提要,因此,當用戶滾動到底部時,在到達最后一個單元格之前,我加載了新帖子,然后將它們插入表格中。
當我這樣做時,我得到了這種奇怪的毛刺效果,即單元格隨機下降(位於前一個單元格之后)到位,表格視圖向上滾動,有點混亂。
我上傳了一個我滾動的剪輯。 當您看到活動指示器時,我停止滾動。 運動的其余部分來自故障行為。
我希望不會,但是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]
時單元格可以完美呈現,因此插入單元格時可能發生了某些錯誤?
當您處理UITableView
故障時:
在您的情況下,可能存在一個問題,即fetchHomeFeedDataForFeedOption:completion:
不在主線程上調用完成塊。
您的插入肯定是錯誤的-對UITableView
所有刪除/插入/更新/移動調用都應包裝在beginUpdates
/ endUpdates
您底部的“加載更多”組件可能是個問題。 您需要解決它如何管理表視圖的contentSize / contentOffset / contentInset。 如果除了操作contentInset之外沒有執行其他任何操作-它將執行錯誤的工作。
盡管很難調試整個解決方案,但我敢打賭選項2和3是關鍵問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.