Have a reloadData for a UITableView animate when changing

前端 未结 17 2881
感动是毒
感动是毒 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:45

    To reload all sections, not just one with custom duration.

    User duration parameter of UIView.animate to set custom duration.

    UIView.animate(withDuration: 0.4, animations: { [weak self] in
        guard let `self` = self else { return }
        let indexSet = IndexSet(integersIn: 0..<self.tableView.numberOfSections)
        self.tableView.reloadSections(indexSet, with: UITableView.RowAnimation.fade)
    })
    
    0 讨论(0)
  • Have more freedom using CATransition class.

    It isn't limited to fading, but can do movements as well..


    For example:

    (don't forget to import QuartzCore)

    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionPush;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.fillMode = kCAFillModeForwards;
    transition.duration = 0.5;
    transition.subtype = kCATransitionFromBottom;
    
    [[self.tableView layer] addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];
    

    Change the type to match your needs, like kCATransitionFade etc.

    Implementation in Swift:

    let transition = CATransition()
    transition.type = kCATransitionPush
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.fillMode = kCAFillModeForwards
    transition.duration = 0.5
    transition.subtype = kCATransitionFromTop
    self.tableView.layer.addAnimation(transition, forKey: "UITableViewReloadDataAnimationKey")
    // Update your data source here
    self.tableView.reloadData()
    

    Reference for CATransition

    Swift 5:

    let transition = CATransition()
    transition.type = CATransitionType.push
    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    transition.fillMode = CAMediaTimingFillMode.forwards
    transition.duration = 0.5
    transition.subtype = CATransitionSubtype.fromTop
    self.tableView.layer.add(transition, forKey: "UITableViewReloadDataAnimationKey")
    // Update your data source here
    self.tableView.reloadData()
    
    0 讨论(0)
  • 2020-11-28 17:51

    For Swift 4

    tableView.reloadSections([0], with: UITableView.RowAnimation.fade)
    
    0 讨论(0)
  • 2020-11-28 17:54

    I can't comment on the top answer, but a swift implementation would be:

    self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)
    

    you could include as many sections as you want to update in the first argument for reloadSections.

    Other animations available from the docs: https://developer.apple.com/reference/uikit/uitableviewrowanimation

    fade The inserted or deleted row or rows fade into or out of the table view.

    right The inserted row or rows slide in from the right; the deleted row or rows slide out to the right.

    left The inserted row or rows slide in from the left; the deleted row or rows slide out to the left.

    top The inserted row or rows slide in from the top; the deleted row or rows slide out toward the top.

    bottom The inserted row or rows slide in from the bottom; the deleted row or rows slide out toward the bottom.

    case none The inserted or deleted rows use the default animations.

    middle The table view attempts to keep the old and new cells centered in the space they did or will occupy. Available in iPhone 3.2.

    automatic The table view chooses an appropriate animation style for you. (Introduced in iOS 5.0.)

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

    If you want to add your own custom animations to UITableView cells, use

    [theTableView reloadData];
    [theTableView layoutSubviews];
    NSArray* visibleViews = [theTableView visibleCells];
    

    to get an array of visible cells. Then add any custom animation to each cell.

    Check out this gist I posted for a smooth custom cell animation. https://gist.github.com/floprr/1b7a58e4a18449d962bd

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

    Animating without reloadData() in Swift can be done like this (as of version 2.2):

    tableview.beginUpdates()
    var indexPathsToDeleteForAnimation: [NSIndexPath] = []
    var numOfCellsToRemove = ArrayOfItemsToRemove ?? 0
    
    // Do your work here
    while numOfCellsToRemove > 0 {
        // ...or here, if you need to add/remove the same amount of objects to/from somewhere
        indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
        numOfCellsToRemove -= 1
    }
    tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
    tableview.endUpdates()
    

    in case you need to call reloadData() after the animation ends, you can embrace the changes in CATransaction like this:

    CATransaction.begin()
    CATransaction.setCompletionBlock({() in self.tableview.reloadData() })
    tableview.beginUpdates()
    var indexPathsToDeleteForAnimation: [NSIndexPath] = []
    var numOfCellsToRemove = ArrayOfItemsToRemove.count ?? 0
    
    // Do your work here
    while numOfCellsToRemove > 0 {
         // ...or here, if you need to add/remove the same amount of objects to/from somewhere
         indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
         numOfCellsToRemove -= 1
    }
    tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
    tableview.endUpdates()
    CATransaction.commit()
    

    The logic is shown for the case when you delete rows, but the same idea works also for adding rows. You can also change animation to UITableViewRowAnimation.Left to make it neat, or choose from the list of other available animations.

    0 讨论(0)
提交回复
热议问题