iOS:使用insertRowsAtIndexPaths在UITableview中插入多行

我已经在TableView中有10行我想要做的是添加另外10行,我正在使用insertRowsAtIndexPaths,但我收到错误。

以下是我使用的代码

-(void)insertDownloadedActions:(NSMutableArray *)dataToAdd { __weak CurrentViewController *weakSelf = self; int64_t delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [weakSelf.tableView beginUpdates]; [weakSelf.dataSource addObjects:dataToAdd]; NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:[weakSelf.dataSource count]-dataToAdd.count-1 inSection:0]; [weakSelf.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationTop]; [weakSelf.tableView endUpdates]; }); } 

但是我得到了以下错误

 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (20) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). 

代码很接近,但是表视图需要用索引path更新,与添加到数据源的内容完全一致。

 -(void)insertDownloadedActions:(NSMutableArray *)dataToAdd { // don't need this //__weak CurrentViewController *weakSelf = self; int64_t delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { // build the index paths for insertion // since you're adding to the end of datasource, the new rows will start at count NSMutableArray *indexPaths = [NSMutableArray array]; NSInteger currentCount = self.datasource.count; for (int i = 0; i < dataToAdd.count; i++) { [indexPaths addObject:[NSIndexPath indexPathForRow:currentCount+i inSection:0]]; } // do the insertion [self.dataSource addObjects:dataToAdd]; // tell the table view to update (at all of the inserted index paths) [self.tableView beginUpdates]; [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop]; [self.tableView endUpdates]; }); } 

你想要一个weakSelf来避免块所有者保留块的循环,并且块(通过使用块所有者“self”)保留所有者。 这里没有必要使用weakSelf模式,因为视图控制器不保留已分派块的副本。

insertRowsAtIndexPaths:withRowAnimation: AND对数据模型的更改都需要在 beginUpdatesendUpates 之间 endUpates

我创build了一个应该自己工作的简单例子。 我花了一个星期的时间,试图找出这个问题,因为我找不到任何简单的例子,所以我希望这可以节省一些时间和头痛!

 @interface MyTableViewController () @property (nonatomic, strong) NSMutableArray *expandableArray; @property (nonatomic, strong) NSMutableArray *indexPaths; @property (nonatomic, strong) UITableView *myTableView; @end @implementation MyTableViewController - (void)viewDidLoad { [self setupArray]; } - (void)setupArray { self.expandableArray = @[@"One", @"Two", @"Three", @"Four", @"Five"].mutableCopy; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.expandableArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //here you should create a cell that displays information from self.expandableArray, and return it } //call this method if your button/cell/whatever is tapped - (void)didTapTriggerToChangeTableView { if (/*some condition occurs that makes you want to expand the tableView*/) { [self expandArray] }else if (/*some other condition occurs that makes you want to retract the tableView*/){ [self retractArray] } } //this example adds 1 item - (void)expandArray { //create an array of indexPaths self.indexPaths = [[NSMutableArray alloc] init]; for (int i = theFirstIndexWhereYouWantToInsertYourAdditionalCells; i < theTotalNumberOfAdditionalCellsToInsert + theFirstIndexWhereYouWantToInsertYourAdditionalCells; i++) { [self.indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates [self.myTableView beginUpdates]; //HERE IS WHERE YOU NEED TO ALTER self.expandableArray to have the additional/new data values, eg: [self.expandableArray addObject:@"Six"]; [self.myTableView insertRowsAtIndexPaths:self.indexPaths withRowAnimation:(UITableViewRowAnimationFade)]; //or a rowAnimation of your choice [self.myTableView endUpdates]; } //this example removes all but the first 3 items - (void)retractArray { NSRange range; range.location = 3; range.length = self.expandableArray.count - 3; //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates [self.myTableView beginUpdates]; [self.expandableArray removeObjectsInRange:range]; [self.myTableView deleteRowsAtIndexPaths:self.indexPaths withRowAnimation:UITableViewRowAnimationFade]; //or a rowAnimation of your choice [self.myTableView endUpdates]; } @end 

免费代码,不要敲它。

我不确定这一点,但只是尝试这可能会解决您的问题,这可能是您在调用开始更新后添加数据的问题。 所以在开始更新之前只需更新数据源。