iosswiftuitableviewanimationcontentoffset

Slot machine animation using UITableView


I need to implement slot-machine animation according to provided design and timings.

It should perform infinite scroll, until some event will be triggered. After that animation, it should slow down and stop on defined position

For this task I have used next solution:

var isRolling: Bool = false

func startScroll() {
    isRolling = true

    UIView.animate(
        withDuration: 0.05,
        delay: 0,
        options: .curveLinear,
        animations: {
            self.tableView.contentOffset.y -= self.rowHeight
    },
        completion: { _ in
            if self.isRolling {
                self.startScroll()
            } else {
                self.resetScrollPosition

                UIView.animate(
                    withDuration: 0.7,
                    delay: 0,
                    options: .curveEaseOut,
                    animations: {
                         self.tableView.contentOffset.y -= 8 * self.rowHeight
                },
                    completion: nil
                )
            }
    })
}

private func resetScrollPosition() {
    tableView.reloadData()

    tableView.contentOffset.y = startOffset
    tableView.reloadData()
}

func stopScroll() {
    isRolling = false
}

The problems:

  1. After calling resetScrollPosition, in animations completion block, tableviews contentOffset.y value is updated but tableView stays on the same position. I have tried to change direct contentOffset changing to setContentOffset, scrollToRow, scrollToRect, wrap it in main queue - no changes
  2. Slowing animation should scroll 8 items. It's performed but first 6 items aren't visible during animation, only the last two. Check the issue gif (jump 2 -> 11 is ok): slot animation issue

Solution

  • Replaced UITableView with UIScrollView

    Uploaded code to gist - https://gist.github.com/OlesenkoViktor/76845c5448b421ead0a2303af2b1161d

    Thanks @Paulw11 for his idea