2011-09-25 41 views
32

Bạn sẽ hoạt hình như thế nào - reloadData trên UITableView? Nguồn dữ liệu có trên UIFetchedResultsController vì vậy tôi không thể phát với – insertSections:withRowAnimation:, – deleteSections:withRowAnimation: được gói trong – beginUpdates, – endUpdates.Hoạt ảnh tải lạiData trên UITableView

EDIT: Tôi muốn gọi - reloadData sau khi NSFetchedResultsController nạp lại.

+3

Duplicate này - http: // stackover flow.com/questions/419472/have-a-reloaddata-for-a-uitableview-animate-when-changing - câu trả lời hay có –

Trả lời

83

tôi đã loại phương pháp.

- (void)reloadData:(BOOL)animated 
{ 
    [self reloadData]; 

    if (animated) { 

     CATransition *animation = [CATransition animation]; 
     [animation setType:kCATransitionPush]; 
     [animation setSubtype:kCATransitionFromBottom]; 
     [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
     [animation setFillMode:kCAFillModeBoth]; 
     [animation setDuration:.3]; 
     [[self layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"]; 

    } 
} 
+0

Giải pháp tốt đẹp nếu bạn cần một số hoạt hình tùy chỉnh – voromax

+0

Amazing dung dịch!! – Jason

+0

Giải pháp tuyệt vời! Tôi chỉ có một thứ để thêm vào.Trong trường hợp của tôi, tôi đã gặp vấn đề gây ra TableView trước khi reloadData được cuộn tất cả xuống phía dưới, do đó, khi hoạt hình xảy ra nó đã làm hỏng tất cả các ô và khung của bảng. Tôi có thể giải quyết nó đảm bảo rằng tableView đã được cuộn tất cả lên trên cùng trước khi tải lạiData: [self scrollRectToVisible: CGRectMake (0, 0, 1, 1) animated: NO]; – Pauls

9

Bạn không thể hoạt ảnh reloadData. Bạn sẽ phải sử dụng các phương thức insert..., delete..., move...reloadRows... của chế độ xem bảng để tạo hiệu ứng động.

Điều này khá đơn giản khi sử dụng NSFetchedResultsController. Các tài liệu cho NSFetchedResultsControllerDelegate chứa một tập hợp các phương pháp mẫu mà bạn vừa phải thích ứng với mã của riêng bạn:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
    atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 

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

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


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
    atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
    newIndexPath:(NSIndexPath *)newIndexPath { 

    UITableView *tableView = self.tableView; 

    switch(type) { 

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

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

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

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 
+1

Tôi xin lỗi tôi đã không đề cập đến tôi cần tải lại dữ liệu bảng sau khi 'NSFetchedResultsController'" refetch " . Tôi nghĩ rằng, nó có thể được thực hiện với một số 'CALayer' hoạt hình trên toàn bộ' UITableView' ... Một cái gì đó giống như lớp bảng sao chép, refetch, tải lại dữ liệu, animate layer off ... – user500

27

Bạn có thể tạo ra một hình ảnh động cơ bản của reLoadData sử dụng:

// Reload table with a slight animation 
[UIView transitionWithView:tableViewReference 
        duration:0.5f 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^(void) { 
    [tableViewReference reloadData]; 
} completion:NULL]; 
+0

Trên bất kỳ chuyển tiếp nào khác, dữ liệu bảng điểm không được tải lại cho đến khi bạn bắt đầu cuộn. Bất kỳ ý tưởng tại sao? –

+1

Khi bạn đang cập nhật bảng không có trong luồng chính, bảng có thể không được cập nhật tự động. Trong những trường hợp đó bạn có thể sử dụng: [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; – Vincent

+0

Thao tác này có hoạt động trong khối hoạt ảnh không? –

5

Tôi tạo ra một phương pháp UITableView loại dựa trên giải pháp từ this link.

Nó phải tải lại tất cả các phần của bảng. Bạn có thể chơi với các tùy chọn UITableViewRowAnimation cho các hiệu ứng hoạt ảnh khác nhau.

- (void)reloadData:(BOOL)animated 
{ 
    [self reloadData]; 

    if (animated) 
    { 
     [self reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.numberOfSections)] withRowAnimation:UITableViewRowAnimationBottom]; 
    } 
} 
5
typedef enum { 
    UITableViewRowAnimationFade, 
    UITableViewRowAnimationRight, 
    UITableViewRowAnimationLeft, 
    UITableViewRowAnimationTop, 
    UITableViewRowAnimationBottom, 
    UITableViewRowAnimationNone, 
    UITableViewRowAnimationMiddle, 
    UITableViewRowAnimationAutomatic = 100 
} UITableViewRowAnimation; 

và phương pháp:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; 
14

Bạn chỉ có thể gọi đường dây này khi bạn muốn tải lại toàn bộ bảng với một hình ảnh động:

NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]); 
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range]; 
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade]; 
+0

Đẹp! Đã được tìm kiếm một giải pháp sạch này là nó cho những người không muốn gọi reloadData brute .... – DogCoffee

1

Bạn có thể muốn sử dụng:

Objective-C

/* Animate the table view reload */ 
[UIView transitionWithView:self.tableView 
        duration:0.35f 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^(void) 
{ 
     [self.tableView reloadData]; 
} 
       completion:nil]; 

Swift lựa chọn

UIView.transitionWithView(tableView, 
          duration:0.35, 
          options:.TransitionCrossDissolve, 
          animations: 
{() -> Void in 
    self.tableView.reloadData() 
}, 
          completion: nil); 

Animation:

TransitionNone TransitionFlipFromLeft TransitionFlipFromRight TransitionCurlUp TransitionCurlDown TransitionCrossDissolve TransitionFlipFromTop TransitionFlipFromBottom

Reference

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