将行添加到没有动画的表视图的开头
Add rows to the beginning of a tableview without animation
我想用 begin/endUpdates 向表视图添加行,以防止在我重新加载数据时表视图跳转
这是我的代码
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
[UIView setAnimationsEnabled:NO];
[self.messagesTableView beginUpdates];
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows =
heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
[self.messagesTableView insertRowsAtIndexPaths:rowsInsertIndexPath
withRowAnimation:UITableViewRowAnimationNone];
tableViewOffset.y += heightForNewRows;
[self.messagesTableView endUpdates];
[UIView setAnimationsEnabled:YES];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
}
有时(不是每次)我都会收到此错误
invalid number of rows in section 0.
The number of rows contained in an existing section after
the update (2) must be equal to the number of rows contained in that section
before the update (2), plus or minus the number of rows inserted or deleted
from that section (2 inserted, 0 deleted) and plus or minus the number of
rows moved into or out of that section (0 moved in, 0 moved out).
如何防止此错误?
试试这个,我不确定这是否有效。
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
[UIView setAnimationsEnabled:NO];
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows = heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
tableViewOffset.y += heightForNewRows;
[UIView setAnimationsEnabled:YES];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.messagesTableView beginUpdates];
[self.messagesTableView insertRowsAtIndexPaths:rowsInsertIndexPath
withRowAnimation:UITableViewRowAnimationNone];
[self.messagesTableView endUpdates];
});
}
注意:您可能需要更新 rowsInsertIndexPath
引用以在块内使用(__block
类型)。
如果你不想要动画就直接使用
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows =
heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
tableViewOffset.y += heightForNewRows;
[self.messagesTableView reloadData];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
}
如果想快速跳转到选定的indexPath(带动画或不带动画),可以使用这个功能:
//My function to populate
//tableView is synthesized
-(void)setNewMessage:(NSString*)message{
// ...
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
// if your selectedIndexPath==nil, the table scroll stay in the same position
[self reloadData:selectedIndexPath animated:NO];
}
//My reload data wrapper
-(void)reloadData:(NSIndexPath *)selectedIndexPath animated:(BOOL)animated{
[tableView reloadData];
// atScrollPosition can receive different parameters (eg:UITableViewScrollPositionMiddle)
[tableView scrollToRowAtIndexPath:selectedIndexPath
atScrollPosition:UITableViewScrollPositionTop
animated:animated];
}
有一次我在 tableView 中需要同样的灵活性,而这个功能满足了我的需求。您不需要 "setAnimationsEnabled",只需使用:
[tableView scrollToRowAtIndexPath:nil
atScrollPosition:UITableViewScrollPositionNone
animated:NO];
];
希望对您有所帮助。
我想用 begin/endUpdates 向表视图添加行,以防止在我重新加载数据时表视图跳转
这是我的代码
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
[UIView setAnimationsEnabled:NO];
[self.messagesTableView beginUpdates];
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows =
heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
[self.messagesTableView insertRowsAtIndexPaths:rowsInsertIndexPath
withRowAnimation:UITableViewRowAnimationNone];
tableViewOffset.y += heightForNewRows;
[self.messagesTableView endUpdates];
[UIView setAnimationsEnabled:YES];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
}
有时(不是每次)我都会收到此错误
invalid number of rows in section 0.
The number of rows contained in an existing section after
the update (2) must be equal to the number of rows contained in that section
before the update (2), plus or minus the number of rows inserted or deleted
from that section (2 inserted, 0 deleted) and plus or minus the number of
rows moved into or out of that section (0 moved in, 0 moved out).
如何防止此错误?
试试这个,我不确定这是否有效。
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
[UIView setAnimationsEnabled:NO];
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows = heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
tableViewOffset.y += heightForNewRows;
[UIView setAnimationsEnabled:YES];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.messagesTableView beginUpdates];
[self.messagesTableView insertRowsAtIndexPaths:rowsInsertIndexPath
withRowAnimation:UITableViewRowAnimationNone];
[self.messagesTableView endUpdates];
});
}
注意:您可能需要更新 rowsInsertIndexPath
引用以在块内使用(__block
类型)。
如果你不想要动画就直接使用
- (void)updateTableWithNewRowCount:(NSInteger)rowCount
andNewData:(NSArray *)newData {
// Save the tableview content offset
CGPoint tableViewOffset = [self.messagesTableView contentOffset];
// Turn of animations for the update block
// to get the effect of adding rows on top of TableView
NSMutableArray *rowsInsertIndexPath = [[NSMutableArray alloc] init];
int heightForNewRows = 0;
for (NSInteger i = 0; i < rowCount; i++) {
NSIndexPath *tempIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
[rowsInsertIndexPath addObject:tempIndexPath];
// [self.messages insertObject:[newData objectAtIndex:i] atIndex:i];
[self addMessage:[newData objectAtIndex:i]];
heightForNewRows =
heightForNewRows + [self heightForCellAtIndexPath:tempIndexPath];
}
tableViewOffset.y += heightForNewRows;
[self.messagesTableView reloadData];
[self.messagesTableView setContentOffset:tableViewOffset animated:NO];
}
如果想快速跳转到选定的indexPath(带动画或不带动画),可以使用这个功能:
//My function to populate
//tableView is synthesized
-(void)setNewMessage:(NSString*)message{
// ...
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
// if your selectedIndexPath==nil, the table scroll stay in the same position
[self reloadData:selectedIndexPath animated:NO];
}
//My reload data wrapper
-(void)reloadData:(NSIndexPath *)selectedIndexPath animated:(BOOL)animated{
[tableView reloadData];
// atScrollPosition can receive different parameters (eg:UITableViewScrollPositionMiddle)
[tableView scrollToRowAtIndexPath:selectedIndexPath
atScrollPosition:UITableViewScrollPositionTop
animated:animated];
}
有一次我在 tableView 中需要同样的灵活性,而这个功能满足了我的需求。您不需要 "setAnimationsEnabled",只需使用:
[tableView scrollToRowAtIndexPath:nil
atScrollPosition:UITableViewScrollPositionNone
animated:NO];
];
希望对您有所帮助。