Cập nhậtUITableView: xóa phần với hình ảnh động
Tôi đã đăng giải pháp của tôi cho vấn đề này như một câu trả lời dưới đây. Nó có một cách tiếp cận khác với bản sửa đổi đầu tiên của tôi.
Câu hỏi gốc trước đây tôi hỏi một câu hỏi về SO mà tôi nghĩ giải quyết vấn đề của tôi:
How to deal with non-visible rows during row deletion. (UITableViews)
Tuy nhiên, tôi bây giờ có vấn đề tương tự một lần nữa khi loại bỏ phần từ một UITableView. (chúng nổi lên khi tôi thay đổi số lượng phần/hàng trong bảng).
Trước khi tôi mất bạn vì độ dài cắt của bài đăng của tôi, hãy để tôi nêu rõ vấn đề và bạn có thể đọc nhiều như bạn yêu cầu để cung cấp câu trả lời.
Vấn đề:
Nếu hàng loạt xóa dòng VÀ phần từ một UITableView, các ứng dụng bị treo, đôi khi. Nó phụ thuộc vào cấu hình của bảng và sự kết hợp của các hàng và phần mà tôi chọn để loại bỏ.
Nhật ký nói rằng tôi bị rơi vì nó nói tôi đã không cập nhật các nguồn dữ liệu và bảng đúng:
Invalid update: invalid number of rows in section 5. 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 (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted).
Bây giờ một cách nhanh chóng, trước khi bạn viết câu trả lời rõ ràng, tôi đảm bảo với bạn tôi đã thực sự bổ sung và xóa các hàng và phần chính xác từ dataSource. Giải thích là dài, nhưng bạn sẽ tìm thấy nó dưới đây, theo phương pháp.
Vì vậy, với điều đó, nếu bạn vẫn quan tâm ...
Phương pháp xử lý loại bỏ các bộ phận và các hàng:
- (void)createFilteredTableGroups{
//index set to hold sections to remove for deletion animation
NSMutableIndexSet *sectionsToDelete = [NSMutableIndexSet indexSet];
[sectionsToDelete removeIndex:0];
//array to track cells for deletion animation
NSMutableArray *cellsToDelete = [NSMutableArray array];
//array to track controllers to delete from presentation model
NSMutableArray *controllersToDelete = [NSMutableArray array];
//for each section
for(NSUInteger i=0; i<[tableGroups count];i++){
NSMutableArray *section = [tableGroups objectAtIndex:i];
//controllers to remove
NSMutableIndexSet *controllersToDeleteInCurrentSection = [NSMutableIndexSet indexSet];
[controllersToDeleteInCurrentSection removeIndex:0];
NSUInteger indexOfController = 0;
//for each cell controller
for(ScheduleCellController *cellController in section){
//bool indicating whether the cell controller's cell should be removed
NSString *shouldDisplayString = (NSString*)[[cellController model] objectForKey:@"filteredDataSet"];
BOOL shouldDisplay = [shouldDisplayString boolValue];
//if it should be removed
if(!shouldDisplay){
NSIndexPath *cellPath = [self indexPathOfCellWithCellController:cellController];
//if cell is on screen, mark for animated deletion
if(cellPath!=nil)
[cellsToDelete addObject:cellPath];
//marking controller for deleting from presentation model
[controllersToDeleteInCurrentSection addIndex:indexOfController];
}
indexOfController++;
}
//if removing all items in section, add section to removed in animation
if([controllersToDeleteInCurrentSection count]==[section count])
[sectionsToDelete addIndex:i];
[controllersToDelete addObject:controllersToDeleteInCurrentSection];
}
//copy the unfiltered data so we can remove the data that we want to filter out
NSMutableArray *newHeaders = [tableHeaders mutableCopy];
NSMutableArray *newTableGroups = [[allTableGroups mutableCopy] autorelease];
//removing controllers
int i = 0;
for(NSMutableArray *section in newTableGroups){
NSIndexSet *indexesToDelete = [controllersToDelete objectAtIndex:i];
[section removeObjectsAtIndexes:indexesToDelete];
i++;
}
//removing empty sections and cooresponding headers
[newHeaders removeObjectsAtIndexes:sectionsToDelete];
[newTableGroups removeObjectsAtIndexes:sectionsToDelete];
//update headers
[tableHeaders release];
tableHeaders = newHeaders;
//storing filtered table groups
self.filteredTableGroups = newTableGroups;
//filtering animation and presentation model update
[self.tableView beginUpdates];
tableGroups = self.filteredTableGroups;
[self.tableView deleteSections:sectionsToDelete withRowAnimation:UITableViewRowAnimationTop];
[self.tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
//marking table as filtered
self.tableIsFiltered = YES;
}
tôi đoán:
Các probl em có vẻ như thế này: Nếu bạn nhìn ở trên nơi tôi liệt kê số lượng ô trong mỗi phần, bạn sẽ thấy phần 5 xuất hiện để tăng thêm 1. Tuy nhiên, điều này không đúng. Phần 5 ban đầu đã thực sự bị xóa và một phần khác đã thay thế vị trí của nó (cụ thể, đó là phần 10 cũ).
Vậy tại sao chế độ xem bảng dường như không nhận ra điều này? Nên BIẾT rằng tôi đã xóa phần cũ và không nên mong đợi một phần mới hiện đang nằm ở chỉ mục của mục cũ bị ràng buộc bởi số hàng của phần đã xóa.
Hy vọng điều này có ý nghĩa, có một chút phức tạp khi viết điều này.
(lưu ý mã này đã hoạt động trước với số hàng/phần khác nhau.cấu hình cụ thể này dường như cung cấp cho nó các vấn đề)
Cách khác, theo dõi chỉ mụcPath cho mỗi ô bạn cần loại bỏ và điều chỉnh chúng một cách thích hợp khi bạn thực hiện xóa. (Đây có thể là cách dài/phức tạp/không thích hợp để làm điều đó - chỉ là một ý nghĩ.) – Tim
Tôi đang xóa hàng loạt, vì vậy nó không có sự khác biệt theo thứ tự mà tôi liệt kê các hoạt động. Chế độ xem bảng thực hiện các thao tác "cùng một lúc" khi chúng nằm trong khối cập nhật. Như tôi đã hoang tưởng, tôi đã cố gắng chuyển đổi thứ tự của các hoạt động vô ích. Việc đánh số các phần/hàng không chuyển đổi (không nên chuyển đổi) trong quá trình xóa hàng loạt. Nếu không sử dụng các khối, bạn sẽ chính xác. –
@Tim Thú vị nghĩ. Bạn nói đúng, có thể khá tẻ nhạt với một số lượng lớn các xóa (mà tôi sẽ có). Tôi cũng tự hỏi liệu tôi có thể thực hiện nhiều lần xóa liên tiếp nhanh chóng hay không. Tôi đã cố gắng xóa hàng loạt để tránh những vấn đề này, nhưng nó có thể là cần thiết. –