標籤:
本篇主要介紹使用beginUpdates和endUpdates方法對UITableView的Cell進行大量操作更新。首先給出過程中依賴的資料來源:
self.arraySections = [NSMutableArray arrayWithCapacity:0]; NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"Apple",@"Alice",@"Apache",@"amount",@"application",@"abort",@"action",@"alert", nil]; NSMutableArray *array2 = [NSMutableArray arrayWithObjects:@"BMW",@"Beach",@"Boom",@"Band",@"BBBB",@"baby",@"bear", nil]; NSMutableArray *array3 = [NSMutableArray arrayWithObjects:@"Cache",@"Clean",@"clear",@"Class",@"Client",@"count",@"ccc",@"can",@"ccccca",@"c1618", nil]; [self.arraySections addObject:array1]; [self.arraySections addObject:array2]; [self.arraySections addObject:array3];
beginUpdates和endUpdates方法是一對綁定在一起的方法,用來對UITableView批次更新操作。先看一下多個插入刪除操作不使用beginUpdates和endUpdates的情況:
NSMutableArray *array1 = (NSMutableArray *)self.arraySections[0]; //操作1 刪除 [array1 removeObjectAtIndex:0]; [self.tableMain deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; //操作2 插入 [array1 insertObject:@"insert" atIndex:3]; [self.tableMain insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; //操作...
這種做法對於每一個操作,是嚴格按照順序執行的,先執行操作1,再執行操作2…再執行任意一個操作的時候,先更新資料來源,然後調用表視圖的相關操作,該操作方法執行完畢後,會立即調用相關的代理方法更新表視圖。更新完畢後繼續執行下一個操作…即整個過程是不斷地調用代理方法來更新表視圖。因此對於這種按序更新的方法,每一個更新操作並不是同時進行的,如果有很多個操作,可能通過肉眼就能看出更新的先後,這通常並不是我們想要的。
通過beginUpdates和endUpdates則可以批量處理操作,區別於上面的操作一個一個執行然後不斷更新表視圖,批量處理實現了在所有操作執行完後調用代理方法一次性更新表視圖,這種方法保證了所有操作最終是同時更新的。
beginUpdates和endUpdates批次更新有三部曲:
- 更新資料來源(所有操作)
- 建立相應的indexPaths數組
- 執行操作
下面舉例說明:
NSMutableArray *array1 = (NSMutableArray *)self.arraySections[0]; [array1 removeObjectAtIndex:0]; [array1 removeObjectAtIndex:2]; [array1 insertObject:@"111" atIndex:1]; [array1 insertObject:@"333" atIndex:3]; //建立相應的indexPaths數組 NSArray *indexPathsDelete = @[[NSIndexPath indexPathForRow:0 inSection:0],[NSIndexPath indexPathForRow:2 inSection:0]]; NSArray *indexPathsInsert = @[[NSIndexPath indexPathForRow:1 inSection:0],[NSIndexPath indexPathForRow:3 inSection:0]]; //執行操作 [self.tableMain beginUpdates]; [self.tableMain deleteRowsAtIndexPaths:indexPathsDelete withRowAnimation:UITableViewRowAnimationFade]; [self.tableMain insertRowsAtIndexPaths:indexPathsInsert withRowAnimation:UITableViewRowAnimationFade]; [self.tableMain endUpdates];
beginUpdates和endUpdates方法對之間的操作執行後並沒有立刻更新表視圖,而是等endUpdates方法返回後才調用代理方法一次性更新的,因此所有更新動畫都是同時執行的。
執行前後的表視圖顯示如下:
執行前:
執行後:
執行完這段代碼,產生如下幾個問題:
下面再看一個例子,用來證明問題二中的相關結論。
//更新資料來源 NSMutableArray *array1 = (NSMutableArray *)self.arraySections[0]; NSMutableArray *array3 = (NSMutableArray *)self.arraySections[2]; [array1 removeObjectAtIndex:0]; //刪除第0分組第0記錄 [array1 removeObjectAtIndex:2]; //刪除第0分組第2記錄 [self.arraySections removeObjectAtIndex:1]; //刪除第1分組 [array1 insertObject:@"1111" atIndex:1]; //插入第0分組第1記錄 [array3 insertObject:@"3333" atIndex:0]; //插入第2分組第0記錄 //建立相應的indexPaths數組 NSArray *indexpathsDelete = @[[NSIndexPath indexPathForRow:0 inSection:0],[NSIndexPath indexPathForRow:2 inSection:0]]; NSArray *indexpathsInsert = @[[NSIndexPath indexPathForRow:1 inSection:0],[NSIndexPath indexPathForRow:0 inSection:1]/*要插入的是第2分組第0記錄,但這裡的分組數卻為1,思考原因*/]; //執行操作 [self.tableMain beginUpdates]; [self.tableMain insertRowsAtIndexPaths:indexpathsInsert withRowAnimation:UITableViewRowAnimationFade]; [self.tableMain deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade]; [self.tableMain deleteRowsAtIndexPaths:indexpathsDelete withRowAnimation:UITableViewRowAnimationFade]; [self.tableMain endUpdates];
執行後介面如下:
由於在執行insert之前,delete已經執行完畢了,原始的第1分組已經被刪除了,原始第2分組變為第1分組,因此insert方法所要插入的第二個cell的indexPath對應的section為1而不是2。
總結一下:如果只是單純的一個插入或者刪除操作,沒必要用beginUpdates和endUpdates包裹操作方法;若是大量操作,建議用endUpdates和endUpdates,已保證介面對各個更新操作同時響應。
iOS開發-beginUpdates && endUpdates用法