2014-01-08 39 views
10

我在TableView中已經有10行了我想要做的是爲我使用的insertRowsAtIndexPaths添加另外10行,但出現錯誤。iOS:使用insertRowsAtIndexPaths在UITableview中插入多行

以下是我使用

-(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). 
+0

您只添加一行而不是10 – Abizern

+1

插入該行時,必須同時增加該部分中的行數。 –

+1

如果您從數據源中獲取該數據並將其添加到數據源中,則會自動提取。問題在於,他只是將一個項目插入到他的表格中,而不是將其添加到數據源中的另外10個項目。 – Abizern

回答

23

代碼已關閉,但表視圖需要更新索引路徑,與添加到數據源的內容完全一致。

-(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避免循環,其中塊所有者保留塊和塊(通過使用塊所有者「自我」)保留的所有者。這裏沒有必要使用weakSelf模式,因爲視圖控制器不保留已分派塊的副本。

+0

好的我會檢查這個,你能告訴我爲什麼__weak不是必需的嗎? – Abhishek

+0

查看答案的底部。 – danh

+0

好吧,所以我明白的是,我應該使用__weak只有當我使用塊權利? – Abhishek

0

我不知道這一點,但只是嘗試,這可能是它會解決你的問題,這可能是您在調用開始更新後添加數據的問題。所以只需在開始更新之前更新數據源。

+0

沒有它沒有工作我試過 – Abhishek

+0

這是不正確的。數據必須在beginUpdates和endUpdates之間添加 – jungledev

+0

他是對的,請參閱官方文檔:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html –

1

insertRowsAtIndexPaths:withRowAnimation:和更改您的數據模型都需要發生beginUpdatesendUpates

在兩者之間

我創建了一個簡單的例子,應該對自己的工作。由於找不到任何簡單的例子,我花了一個星期的時間想弄清楚這一點,所以我希望這能節省一些時間和頭痛!

@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 

免費的代碼,不要敲它。