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

iOS:使用InsertRowsatindExpath在UITableview中插入多行,ios,iphone,objective-c,uitableview,Ios,Iphone,Objective C,Uitableview,我在TableView中已经有10行了,我正在尝试添加另外10行,因为我正在使用insertRowsAtIndexPaths,但是我得到了错误 下面是我正在使用的代码 -(void)insertDownloadedActions:(NSMutableArray *)dataToAdd { __weak CurrentViewController *weakSelf = self; int64_t delayInSeconds = 2.0; dis

我在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).

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

代码已经完成,但表视图需要使用与添加到数据源的内容完全对应的索引路径进行更新

-(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];
    });
}
-(void)insertDownloadedActions:(NSMutableArray*)数据添加
{
//我不需要这个
//__弱电视图控制器*weakSelf=self;
int64_t delayunseconds=2.0;
dispatch\u time\u t popTime=dispatch\u time(立即分派时间,延迟间隔*秒秒秒);
调度\u after(popTime,调度\u get\u main\u queue(),^(void){
//构建用于插入的索引路径
//由于要添加到数据源的末尾,新行将从计数开始
NSMutableArray*索引路径=[NSMutableArray];
NSInteger currentCount=self.datasource.count;
对于(int i=0;i

您需要一个weakSelf来避免块所有者保留块和块(通过使用块所有者“self”)保留所有者的循环。这里不需要weakSelf模式,因为视图控制器没有保留已调度块的副本

insertRowsAtIndexPaths:withRowAnimation:
和对数据模型的更改都需要在开始更新和结束更新之间进行

我已经创建了一个简单的示例,它应该能够独立工作。由于找不到任何简单的例子,我花了一个星期的时间试图弄明白这一点,所以我希望这能节省一些人的时间和头痛

@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
@接口MyTableViewController()
@属性(非原子,强)NSMutableArray*expandableArray;
@属性(非原子,强)NSMutableArray*索引路径;
@属性(非原子,强)UITableView*myTableView;
@结束
@MyTableViewController的实现
-(无效)viewDidLoad
{
[自设置阵列];
}
-(void)设置数组
{
self.expandableArray=@[@“一”,“二”,“三”,“四”,“五]。mutableCopy;
}
-(NSInteger)表格视图中的节数:(UITableView*)表格视图
{
返回1;
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节
{
返回self.expandableArray.count;
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
//在这里,您应该创建一个单元格,显示self.expandableArray中的信息,并返回它
}
//如果点击了按钮/单元格/任何内容,请调用此方法
-(void)didTapTriggerToChangeTableView
{
如果(/*出现某种情况,使您希望展开tableView*/){
[自扩展阵列]
}否则,如果(/*发生其他一些情况,使您想收回tableView*/){
[自伸缩阵列]
}
}
//此示例添加了1项
-(void)扩展数组
{
//创建一个索引路径数组
self.indexPaths=[[NSMutableArray alloc]init];
对于(int i=要插入附加单元格的第一个索引;i<要插入的附加单元格总数+要插入附加单元格的第一个索引;i++){
[self.indexPaths addObject:[NSIndexPath indexPathForRow:i第0节];
}
//修改数组并在BeginUpdate和EndUpdate之间调用insertRowsAtIndexPaths:withRowAnimation:InBeginUpdate
[self.myTableView开始更新];
//这里是您需要更改self.expandableArray以获得附加/新数据值的地方,例如:
[self.expandableArray addObject:@“六个”];
[self.myTableView insertRowsAtIndexPaths:self.InExpaths with rowAnimation:(UITableViewRowAnimationFade)];//或您选择的rowAnimation
[self.myTableView endUpdates];
}
//本例删除除前3项外的所有项
-(void)数组
{
NSRange范围;
range.location=3;
range.length=self.expandableArray.count-3;
//修改数组并在BeginUpdate和EndUpdate之间调用insertRowsAtIndexPaths:withRowAnimation:InBeginUpdate
[self.myTableView开始更新];
[self.expandableArray removeObjectsInRange:range];
[self.myTableView deleteRowsAtIndexPaths:self.indexPaths with rowAnimation:UITableViewRowAnimationFade];//或您选择的rowAnimation
[self.myTableView endUpdates];
}
@结束

免费代码,不要敲它。

在swift中,要添加多行,我们可以

let indexPaths = (0 ..< messageList.count).map { IndexPath(row: $0, section: 0) }
self.chatTableView.beginUpdates()
self.chatTableView.insertRows(at: indexPaths, with: .bottom)
self.chatTableView.endUpdates()
let IndexPath=(0..

这里我插入到
indexPath:0
,因为我想在向上滚动时附加列表。(反向分页)

您只添加了一行,而不是10行。插入行时,您必须同时增加节中的行数。如果您是从数据源获取该行并将项目添加到数据源,则会自动获取该行数。问题是,他只在表中插入了一项,而不是在数据源中添加了10项。我可以在CellForRowatineXpath上查看您的代码吗?谢谢@Abizern问题是唯一的,但现在我有了