Have a reloadData for a UITableView animate when changing

前端 未结 17 2882
感动是毒
感动是毒 2020-11-28 17:25

I have a UITableView that has two modes. When we switch between the modes I have a different number of sections and cells per section. Ideally, it would do some cool anima

相关标签:
17条回答
  • 2020-11-28 17:56

    Actually, it's very simple:

    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
    

    From the documentation:

    Calling this method causes the table view to ask its data source for new cells for the specified sections. The table view animates the insertion of new cells in as it animates the old cells out.

    0 讨论(0)
  • 2020-11-28 17:58

    In my case, I wanted to add 10 more rows into the tableview (for a "show more results" type of functionality) and I did the following:

      NSInteger tempNumber = self.numberOfRows;
      self.numberOfRows += 10;
      NSMutableArray *arrayOfIndexPaths = [[NSMutableArray alloc] init];
      for (NSInteger i = tempNumber; i < self.numberOfRows; i++) {
        [arrayOfIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
      }
      [self.tableView beginUpdates];
      [self.tableView insertRowsAtIndexPaths:arrayOfIndexPaths withRowAnimation:UITableViewRowAnimationTop];
      [self.tableView endUpdates];
    

    In most cases, instead of "self.numberOfRows", you would usually use the count of the array of objects for the tableview. So to make sure this solution works well for you, "arrayOfIndexPaths" needs to be an accurate array of the index paths of the rows being inserted. If the row exists for any of this index paths, the code might crash, so you should use the method "reloadRowsAtIndexPaths:withRowAnimation:" for those index pathds to avoid crashing

    0 讨论(0)
  • 2020-11-28 17:59
    CATransition *animation = [CATransition animation];
    animation.duration = .3;
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromLeft];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [animation setDuration:.3];
    
    [[_elementTableView layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];
    
    [tableView reloadData];
    
    0 讨论(0)
  • 2020-11-28 18:02

    All of these answers assume that you are using a UITableView with only 1 section.

    To accurately handle situations where you have more than 1 section use:

    NSRange range = NSMakeRange(0, myTableView.numberOfSections);
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
    [myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
    

    (Note: you should make sure that you have more than 0 sections!)

    Another thing to note is that you may run into a NSInternalInconsistencyException if you attempt to simultaneously update your data source with this code. If this is the case, you can use logic similar to this:

    int sectionNumber = 0; //Note that your section may be different
    
    int nextIndex = [currentItems count]; //starting index of newly added items
    
    [myTableView beginUpdates];
    
    for (NSObject *item in itemsToAdd) {
        //Add the item to the data source
        [currentItems addObject:item];
    
        //Add the item to the table view
        NSIndexPath *path = [NSIndexPath indexPathForRow:nextIndex++ inSection:sectionNumber];
        [myTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    
    [myTableView endUpdates];
    
    0 讨论(0)
  • 2020-11-28 18:03

    Swift 4 version for @dmarnel answer:

    tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
    
    0 讨论(0)
  • 2020-11-28 18:05

    You might want to use:

    Objective-C

    [UIView transitionWithView: self.tableView
                      duration: 0.35f
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^(void)
     {
          [self.tableView reloadData];
     }
                    completion: nil];
    

    Swift

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

    Swift 3, 4 & 5

    UIView.transition(with: tableView,
                      duration: 0.35,
                      options: .transitionCrossDissolve,
                      animations: { self.tableView.reloadData() }) // left out the unnecessary syntax in the completion block and the optional completion parameter
    

    No hassles. :D

    You can also use any of the UIViewAnimationOptionTransitions you want for cooler effects:

    • transitionNone
    • transitionFlipFromLeft
    • transitionFlipFromRight
    • transitionCurlUp
    • transitionCurlDown
    • transitionCrossDissolve
    • transitionFlipFromTop
    • transitionFlipFromBottom
    0 讨论(0)
提交回复
热议问题