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:
UITableViewwithfixed-heightcell. It is the same cell with the only difference - icon or text (depends onindexPath.row)Scrollis only down-to-up that's why I'm using last cell as start point inresetScrollPositionmethod- If first element reached, scroll position resets to start point
- Animation performed as
contentOffsetchange with linear option. In completion block, if animation is still needed, it's called again. If don't needed - slowing animation witheaseOutoption started
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:
- After calling
resetScrollPosition, in animations completion block, tableviewscontentOffset.yvalue is updated buttableViewstays on the same position. I have tried to change directcontentOffsetchanging tosetContentOffset,scrollToRow,scrollToRect, wrap it in main queue - no changes - 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):

Replaced
UITableViewwithUIScrollViewUploaded code to gist - https://gist.github.com/OlesenkoViktor/76845c5448b421ead0a2303af2b1161d
Thanks @Paulw11 for his idea