2009-07-25 23 views
7

Tôi đang làm việc để sửa đổi một số mã nặng tay hiện có mà chỉ cần gọi [tableView reloadData] về bất kỳ thay đổi nào, sử dụng các cập nhật bảng cụ thể hơn với các phương pháp chèn/xóa.Chèn UITableView: withRowAnimation: làm cho tất cả các ô bảng được yêu cầu

Tuy nhiên, tôi nhận được một số hành vi thực sự xấu khi làm như vậy. Trước đây, như người ta sẽ tưởng tượng, khi bảng được nạp, nó chỉ yêu cầu các ô cho các hàng được hiển thị tại thời điểm đó. Đây là hành vi khi sử dụng reloadData.

Hiện tại, insertSections đang được gọi, tất cả các ô được yêu cầu sau lần cập nhật đó, có thể là hàng trăm. Điều này dẫn đến các tế bào được tạo ra cho mỗi hàng, phá hủy hoàn toàn hàng đợi tế bào có thể tái sử dụng và tất cả chỉ là lãng phí. Tôi phải đang làm điều gì đó sai.

Sự thay đổi này là đơn giản, mã có kết quả trong tableView hỏi chỉ dành cho hàng có thể nhìn thấy:

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 
    // ... ensure it's the right key 
    [tableView reloadData]; 
} 

Mã mà kết quả trong tableView yêu cầu tất cả mọi thứ:

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 
    // ... ensure it's the right key 
    NSUInteger sectionCount = [self sectionCount]; 
    NSIndexSet *indices = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)]; 
    [tableView insertSections:indices withRowAnimation:UITableViewRowAnimationFade]; 
} 

tôi có thể chuyển đổi trở lại và ra để xem thay đổi hành vi. Bực bội. Ý tưởng?


Thêm tiền thưởng chỉ để xem có ai có thông tin chi tiết hơn không.

beginUpdates/endUpdates không ảnh hưởng đến bất cứ điều gì và tôi không mong đợi nó, đây chỉ là một lệnh, không có gì thêm để kết hợp thành một bản cập nhật duy nhất.

Tôi nghĩ đây chỉ đơn giản là tác dụng phụ của mong muốn hoạt ảnh. Để có mọi thứ "trượt" vào, nó phải có mọi thứ để render. Trò chơi kết thúc.

+0

Bạn xác định rằng tất cả các ô được yêu cầu cùng một lúc như thế nào? Không ai được dequeued? – Pascal

+0

Tôi đã tạo một dự án thử nghiệm nhỏ và có thể tái tạo hành vi bạn đang quan sát. Nó thực sự là tò mò.Không thể là hoạt ảnh một mình vì hành vi là như nhau nếu bạn chỉ định UITableViewRowAnimationNone. Sự cố không xảy ra nếu vị trí chèn không hiển thị trên màn hình khi các phần chèn: withRowAnimation: được gọi. –

Trả lời

6

Dường như bạn đang yêu cầu bảng chèn tất cả các phần, về cơ bản tương đương với tải lại. Khi bạn nói với bảng nó cần tải một phần nó cần đọc tất cả các mục trong phần đó. Ngoài ra, bạn đang làm việc đó bên ngoài khối beginUpdates/endUpdates, có nghĩa là mỗi khi bạn thêm vào phần, bảng phải ngay lập tức cam kết các thay đổi. Nếu bạn bọc mọi thứ bên trong startUpdates/endUpdates, nó sẽ tạm dừng tất cả các truy vấn cho đến khi nó được thực hiện, nó sẽ cho phép hệ thống kết hợp các truy vấn dư thừa và loại bỏ các truy vấn không cần thiết.

Bạn chỉ nên gọi các phần chèn với các phần mới được thêm vào. Nếu bạn làm điều đó thì tableview không phải truy vấn thông tin của tất cả các phần chưa được thay đổi, ngay cả khi chúng di chuyển xung quanh. Ngoài ra, nếu các phần tử bên trong một phần thay đổi nhưng chính phần đó thì bạn không nên sử dụng phiên bản hàng của các phương thức để sửa đổi các hàng cụ thể đó trong phần, và chỉ những hàng đó sẽ được truy vấn.

Dưới đây là một ví dụ (từ một ứng dụng dựa trên CoreData) mà nên có được điểm trên. Vì bạn có một mô hình tùy chỉnh thay vì một NSFetchedResultsController, bạn sẽ phải tìm ra loại hành động đang diễn ra thay vì chỉ kiểm tra một loạt các hằng số được hệ thống cung cấp cho bạn.

//Calculate what needs to be changed  

[self.tableView beginUpdates]; 

for (i = 0 i < changeCount; i++) { 
    type = changes[i]; 

    switch(type) { 
    case NSFetchedResultsChangeInsert: 
     [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
        withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
        withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
    } 
} 

switch(type) { 

    case NSFetchedResultsChangeInsert: 
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
    break; 

    case NSFetchedResultsChangeDelete: 
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
    break; 

    case NSFetchedResultsChangeUpdate: 
    [self configureCell:(id)[tableView cellForRowAtIndexPath:indexPath] 
      atIndexPath:indexPath]; 
    break; 

    case NSFetchedResultsChangeMove: 
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] 
        withRowAnimation:UITableViewRowAnimationFade]; 
    break; 
    } 
} 

[self.tableView endUpdates]; 
+0

Vâng, tại ít thông tin bổ sung có thể hữu ích, đây là một bảng hoàn toàn trống rỗng ban đầu. Tôi trì hoãn việc tải dữ liệu để giữ cho giao diện người dùng phản hồi nhanh chóng, vì vậy nó sẽ xuất hiện trống và thêm các phần khi chúng ra khỏi mạng. Vì vậy, đi từ không có phần nào cho tất cả các phần bằng cách sử dụng reloadData hoạt động tốt, nhưng rõ ràng thêm phần kết quả trong hỗn loạn? Kỳ dị. –

+0

Không, dự kiến ​​và tại sao bạn cần các cuộc gọi beginUpdates/endUpdates gói những gì bạn đang làm. Nếu không có những tableView thì giả định rằng sau mỗi sửa đổi bạn làm sẽ có thể tác động đến màn hình, nghĩa là nó phải truy vấn tất cả các phần để tính toán các ô nào có thể nhìn thấy, và sau đó nhận được tất cả các ô đó sẽ được hiển thị. Khi bạn làm một beginUpdates tableView dừng cập nhật cho đến khi bạn gọi endUpdates, tại thời điểm đó nó có thể làm điều đó tất cả một lần với truy vấn tất cả các trạng thái trung gian của bạn. –

+0

"mà không cần truy vấn trạng thái trung gian của bạn," tôi cần thêm coffe –

Các vấn đề liên quan