Table view cell load animation one after another

后端 未结 7 981
面向向阳花
面向向阳花 2021-01-31 05:32

I need to animate the load of the table view rows. When the table reloads the data I need the rows get in from the left one after another. How can I achieve this?

7条回答
  •  有刺的猬
    2021-01-31 06:29

    Swift 4

    I made a quick extension on UITableView to animate cells:

    tableView.reloadData() // To make sure tableView.visibleCells is not empty
    
    tableView.animateCells(
          cells: tableView.visibleCells,
          duration: 0.3,
          delay: 0.5,
          dampingRatio: 0.8,
          configure: { cell -> (prepare: () -> Void, animate: () -> Void)? in
            guard let customCell = cell as? CustomCell else { return nil }
            let preparations = {
              customCell.iconImageView.alpha = 0
            }
            let animations = {
              customCell.iconImageView.alpha = 1
            }
            return (preparations, animations)
        }, completion: {
          print("Cell animations are completed")
        })
    

    The extension looks like this:

    extension UITableView {
      func animateCells(cells: [Cell],
                                               duration: TimeInterval,
                                               delay: TimeInterval = 0,
                                               dampingRatio: CGFloat = 0,
                                               configure: @escaping (Cell) -> (prepare: () -> Void, animate: () -> Void)?,
                                               completion: @escaping () -> Void) {
        var cellDelay: TimeInterval = 0
        var completionCount: Int = 0
    
        for cell in cells {
          if let callbacks = configure(cell) {
            callbacks.prepare()
    
            let animator = UIViewPropertyAnimator(duration: duration, dampingRatio: dampingRatio)
    
            animator.addAnimations(callbacks.animate)
    
            let completionTime = cellDelay + (duration * TimeInterval(dampingRatio))
    
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + completionTime) {
              completionCount += 1
              if completionCount == cells.count {
                completion()
              }
            }
    
            animator.startAnimation(afterDelay: cellDelay)
    
            cellDelay += delay
          } else {
            completionCount += 1
          }
        }
      }
    }
    

提交回复
热议问题