Skip to content

Instantly share code, notes, and snippets.

@jongwonwoo
Created April 22, 2017 06:30
Show Gist options
  • Save jongwonwoo/55decfaa90f0b625534d94d8681d0a24 to your computer and use it in GitHub Desktop.
Save jongwonwoo/55decfaa90f0b625534d94d8681d0a24 to your computer and use it in GitHub Desktop.

Revisions

  1. jongwonwoo created this gist Apr 22, 2017.
    73 changes: 73 additions & 0 deletions JWScrollStateMachine.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    //
    // JWScrollStateMachine.swift
    // JWThumbnailsNavigation
    //
    // Created by Jongwon Woo on 26/03/2017.
    // Copyright © 2017 CocoaPods. All rights reserved.
    //

    import UIKit

    enum JWScrollEvent: Int {
    case beginDragging
    case didScroll
    case willEndDragging
    case didEndDraggingAndNotDecelerating
    case didEndDraggingAndDecelerating
    case willBeginDecelerating
    case didEndDecelerating
    case didEndScrollingAnimation
    }

    @objc enum JWScrollState: Int {
    case beginDragging
    case dragging
    case beginDecelerating
    case decelerating
    case stop
    }

    @objc protocol JWScrollStateMachineDelegate {

    func scrollStateMachine(_ stateMachine: JWScrollStateMachine, didChangeState state: JWScrollState)

    }

    class JWScrollStateMachine: NSObject {

    weak var delegate: JWScrollStateMachineDelegate?

    private var state: JWScrollState = .stop {
    didSet {
    switch state {
    case .dragging, .decelerating, .stop:
    self.delegate?.scrollStateMachine(self, didChangeState: self.state)
    default:
    break
    }
    }
    }

    func scrolling(_ event: JWScrollEvent) {
    switch event {
    case .beginDragging:
    state = .beginDragging
    case .didScroll:
    if state == .beginDragging || state == .dragging {
    state = .dragging
    } else if state == .beginDecelerating || state == .decelerating {
    state = .decelerating
    }
    case .didEndDraggingAndNotDecelerating:
    state = .stop
    case .willBeginDecelerating:
    state = .beginDecelerating
    case .didEndDecelerating:
    if state != .stop {
    state = .stop
    }
    default:
    break
    }
    }
    }