-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGravityScroller.swift
More file actions
122 lines (107 loc) · 3.95 KB
/
GravityScroller.swift
File metadata and controls
122 lines (107 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// GravityScroller.swift
// CoreMotionTest
//
// Created by 张逸 on 15/12/8.
// Copyright © 2015年 Monzy. All rights reserved.
//
import UIKit
import CoreMotion
class GravityScroller: AnyObject {
enum Direction: CGFloat {
case Normal = 1
case UpsideDown = -1
}
static var speed: CGFloat = 0.8 {
didSet {
if speed > 1 {
speed = 1
} else if speed <= 0 {
stop()
}
}
}
static var stableAmount: CGFloat = 0.07
static var originAccelerationY: CGFloat?
static var baseOffsetY: CGFloat?
static var motionManager: CMMotionManager!
static var tableView: UITableView!
static var isPause = false
static var direction: Direction!
static var bottomOffsetMaxHeight: CGFloat = 0
static func initAccelerometer(withTableView _tableView: UITableView, andMotionManager _motionManager: CMMotionManager, withDirection _direction: Direction = .Normal) {
tableView = _tableView
motionManager = _motionManager
direction = _direction
}
static func start(onTop onTop: Void -> Void, onBottom: Void -> Void) {
if tableView == nil || motionManager == nil {
return
}
if motionManager.accelerometerAvailable {
print("active")
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
data, error in
if isPause {
return
}
var pre: CGFloat = 1
var accelerationY = CGFloat((data?.acceleration.y)!)
if originAccelerationY == nil {
print("offsetY: \(tableView.contentOffset.y)")
baseOffsetY = tableView.contentOffset.y
originAccelerationY = accelerationY
}
accelerationY = accelerationY - originAccelerationY!
if accelerationY > 0 {
pre = 1
} else if accelerationY < 0 {
pre = -1
}
pre = pre * (direction.rawValue)
if abs(accelerationY) < stableAmount {
return
}
accelerationY = (abs(accelerationY) - stableAmount)
//up to -1, down to 1, plain to 0
let offsetY = accelerationY * accelerationY * pre * tableView.frame.height * speed
if (tableView.contentOffset.y + offsetY) < baseOffsetY! {
onTop()
UIView.animateWithDuration(0.1, animations: {
tableView.contentOffset = CGPoint(x: tableView.contentOffset.x, y: baseOffsetY!)
})
} else if (tableView.contentOffset.y + offsetY) > (tableView.contentSize.height - tableView.bounds.height) {
onBottom()
UIView.animateWithDuration(0.1, animations: {
tableView.contentOffset = CGPoint(x: tableView.contentOffset.x, y: tableView.contentSize.height - tableView.bounds.height)
})
} else {
UIView.animateWithDuration(0.1, animations: {
tableView.contentOffset = CGPoint(x: tableView.contentOffset.x, y: offsetY + tableView.contentOffset.y)
})
}
}
} else {
print("not active")
}
}
static func stop() {
baseOffsetY = nil
originAccelerationY = nil
tableView = nil
if motionManager != nil {
motionManager.stopAccelerometerUpdates()
}
}
static func pause() {
isPause = true
}
static func play() {
isPause = false
}
static func restart() {
baseOffsetY = nil
originAccelerationY = nil
play()
}
}