react-native-keyboard-controller 1.20.5 → 1.20.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/animations/KeyboardAnimation.swift +10 -1
- package/ios/animations/SpringAnimation.swift +1 -1
- package/ios/animations/TimingAnimation.swift +1 -1
- package/ios/extensions/Notification.swift +1 -0
- package/ios/interactive/KeyboardAreaExtender.swift +1 -1
- package/ios/observers/movement/observer/KeyboardMovementObserver+Lifecycle.swift +0 -12
- package/ios/observers/movement/observer/KeyboardMovementObserver+Listeners.swift +11 -6
- package/ios/observers/movement/observer/KeyboardMovementObserver+Watcher.swift +4 -0
- package/ios/observers/movement/observer/KeyboardMovementObserver.swift +51 -3
- package/package.json +1 -1
|
@@ -23,13 +23,18 @@ public class KeyboardAnimation: KeyboardAnimationProtocol {
|
|
|
23
23
|
// constructor variables
|
|
24
24
|
let fromValue: Double
|
|
25
25
|
let toValue: Double
|
|
26
|
+
let duration: Double
|
|
26
27
|
let speed: Double
|
|
27
28
|
let timestamp: CFTimeInterval
|
|
29
|
+
// internal state
|
|
30
|
+
var lastValue: Double
|
|
28
31
|
|
|
29
|
-
init(fromValue: Double, toValue: Double, animation: CAMediaTiming) {
|
|
32
|
+
init(fromValue: Double, toValue: Double, animation: CAMediaTiming, duration: Double) {
|
|
30
33
|
self.fromValue = fromValue
|
|
31
34
|
self.toValue = toValue
|
|
32
35
|
self.animation = animation
|
|
36
|
+
self.duration = duration
|
|
37
|
+
lastValue = fromValue
|
|
33
38
|
speed = Double(animation.speed)
|
|
34
39
|
timestamp = CACurrentMediaTime()
|
|
35
40
|
}
|
|
@@ -48,6 +53,10 @@ public class KeyboardAnimation: KeyboardAnimationProtocol {
|
|
|
48
53
|
return fromValue < toValue
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
var isFinished: Bool {
|
|
57
|
+
return lastValue == toValue
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
func valueAt(time _: Double) -> Double {
|
|
52
61
|
fatalError("Method is not implemented in abstract class!")
|
|
53
62
|
}
|
|
@@ -57,7 +57,7 @@ public final class SpringAnimation: KeyboardAnimation {
|
|
|
57
57
|
bUnder = 0
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
super.init(fromValue: fromValue, toValue: toValue, animation: animation)
|
|
60
|
+
super.init(fromValue: fromValue, toValue: toValue, animation: animation, duration: animation.settlingDuration)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// public functions
|
|
@@ -30,7 +30,7 @@ public final class TimingAnimation: KeyboardAnimation {
|
|
|
30
30
|
self.p1 = p1
|
|
31
31
|
self.p2 = p2
|
|
32
32
|
|
|
33
|
-
super.init(fromValue: fromValue, toValue: toValue, animation: animation)
|
|
33
|
+
super.init(fromValue: fromValue, toValue: toValue, animation: animation, duration: animation.duration)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// MARK: public functions
|
|
@@ -25,18 +25,6 @@ public extension KeyboardMovementObserver {
|
|
|
25
25
|
name: UIResponder.keyboardWillShowNotification,
|
|
26
26
|
object: nil
|
|
27
27
|
)
|
|
28
|
-
NotificationCenter.default.addObserver(
|
|
29
|
-
self,
|
|
30
|
-
selector: #selector(keyboardDidAppear),
|
|
31
|
-
name: UIResponder.keyboardDidShowNotification,
|
|
32
|
-
object: nil
|
|
33
|
-
)
|
|
34
|
-
NotificationCenter.default.addObserver(
|
|
35
|
-
self,
|
|
36
|
-
selector: #selector(keyboardDidDisappear),
|
|
37
|
-
name: UIResponder.keyboardDidHideNotification,
|
|
38
|
-
object: nil
|
|
39
|
-
)
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
@objc func unmount() {
|
|
@@ -14,8 +14,8 @@ extension KeyboardMovementObserver {
|
|
|
14
14
|
tag = UIResponder.current.reactViewTag
|
|
15
15
|
let keyboardHeight = keyboardFrame.cgRectValue.size.height
|
|
16
16
|
self.keyboardHeight = keyboardHeight
|
|
17
|
+
self.notification = notification
|
|
17
18
|
self.duration = duration
|
|
18
|
-
didShowDeadline = Date.currentTimeStamp + Int64(duration)
|
|
19
19
|
|
|
20
20
|
onRequestAnimation()
|
|
21
21
|
onEvent("onKeyboardMoveStart", Float(self.keyboardHeight) as NSNumber, 1, duration as NSNumber, tag)
|
|
@@ -30,6 +30,11 @@ extension KeyboardMovementObserver {
|
|
|
30
30
|
guard !UIResponder.isKeyboardPreloading else { return }
|
|
31
31
|
let (duration, _) = notification.keyboardMetaData()
|
|
32
32
|
tag = UIResponder.current.reactViewTag
|
|
33
|
+
self.notification = notification
|
|
34
|
+
// when keyboard disappears immediately replace the keyboard frame with .zero
|
|
35
|
+
// since this will be the final frame of the keyboard after animation
|
|
36
|
+
self.notification?.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] =
|
|
37
|
+
NSValue(cgRect: CGRect(x: 0, y: 0, width: 0, height: 0))
|
|
33
38
|
self.duration = duration
|
|
34
39
|
|
|
35
40
|
onRequestAnimation()
|
|
@@ -44,10 +49,8 @@ extension KeyboardMovementObserver {
|
|
|
44
49
|
@objc func keyboardDidAppear(_ notification: Notification) {
|
|
45
50
|
guard !UIResponder.isKeyboardPreloading else { return }
|
|
46
51
|
|
|
47
|
-
let timestamp = Date.currentTimeStamp
|
|
48
52
|
let (duration, frame) = notification.keyboardMetaData()
|
|
49
53
|
if let keyboardFrame = frame {
|
|
50
|
-
let (position, _) = keyboardTrackingView.view.frameTransitionInWindow
|
|
51
54
|
let keyboardHeight = keyboardFrame.cgRectValue.size.height
|
|
52
55
|
tag = UIResponder.current.reactViewTag
|
|
53
56
|
self.keyboardHeight = keyboardHeight
|
|
@@ -57,9 +60,7 @@ extension KeyboardMovementObserver {
|
|
|
57
60
|
return
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
// so we just read actual keyboard frame value in this case
|
|
62
|
-
let height = timestamp >= didShowDeadline ? self.keyboardHeight : position - KeyboardAreaExtender.shared.offset
|
|
63
|
+
let height = self.keyboardHeight - KeyboardAreaExtender.shared.offset
|
|
63
64
|
// always limit progress to the maximum possible value
|
|
64
65
|
let progress = min(height / self.keyboardHeight, 1.0)
|
|
65
66
|
|
|
@@ -70,6 +71,10 @@ extension KeyboardMovementObserver {
|
|
|
70
71
|
removeKeyboardWatcher()
|
|
71
72
|
setupKVObserver()
|
|
72
73
|
animation = nil
|
|
74
|
+
|
|
75
|
+
NotificationCenter.default.post(
|
|
76
|
+
name: .keyboardDidAppear, object: notification, userInfo: nil
|
|
77
|
+
)
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
|
|
@@ -40,6 +40,9 @@ extension KeyboardMovementObserver {
|
|
|
40
40
|
prevKeyboardPosition = keyboardPosition
|
|
41
41
|
|
|
42
42
|
if let animation = animation {
|
|
43
|
+
if animation.isFinished {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
43
46
|
let baseDuration = animation.timingAt(value: keyboardPosition)
|
|
44
47
|
|
|
45
48
|
#if targetEnvironment(simulator)
|
|
@@ -59,6 +62,7 @@ extension KeyboardMovementObserver {
|
|
|
59
62
|
// but CASpringAnimation can never get to this final destination
|
|
60
63
|
let race: (CGFloat, CGFloat) -> CGFloat = animation.isIncreasing ? max : min
|
|
61
64
|
keyboardPosition = race(position, keyboardPosition)
|
|
65
|
+
animation.lastValue = keyboardPosition
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
onEvent(
|
|
@@ -19,7 +19,30 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
19
19
|
var onCancelAnimation: () -> Void
|
|
20
20
|
// progress tracker
|
|
21
21
|
@objc public var keyboardTrackingView = KeyboardTrackingView()
|
|
22
|
-
var animation: KeyboardAnimation?
|
|
22
|
+
var animation: KeyboardAnimation? {
|
|
23
|
+
didSet {
|
|
24
|
+
keyboardDidTask?.cancel()
|
|
25
|
+
|
|
26
|
+
guard let animation = animation, let notification = notification else {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let toValue = animation.toValue
|
|
31
|
+
let duration = animation.duration
|
|
32
|
+
|
|
33
|
+
let task = DispatchWorkItem { [weak self] in
|
|
34
|
+
guard let self = self else { return }
|
|
35
|
+
if toValue > 0 {
|
|
36
|
+
self.keyboardDidAppear(notification)
|
|
37
|
+
} else {
|
|
38
|
+
self.keyboardDidDisappear(notification)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
keyboardDidTask = task
|
|
43
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + duration, execute: task)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
23
46
|
|
|
24
47
|
var prevKeyboardPosition = 0.0
|
|
25
48
|
var displayLink: CADisplayLink!
|
|
@@ -32,9 +55,34 @@ public class KeyboardMovementObserver: NSObject {
|
|
|
32
55
|
set { _keyboardHeight = newValue }
|
|
33
56
|
}
|
|
34
57
|
|
|
35
|
-
var duration = 0
|
|
58
|
+
var duration = 0 {
|
|
59
|
+
didSet {
|
|
60
|
+
keyboardDidTask?.cancel()
|
|
61
|
+
|
|
62
|
+
guard let notification = notification,
|
|
63
|
+
let height = notification.keyboardMetaData().1?.cgRectValue.size.height, duration == 0
|
|
64
|
+
else {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let task = DispatchWorkItem { [weak self] in
|
|
69
|
+
guard let self = self else { return }
|
|
70
|
+
if height > 0 {
|
|
71
|
+
self.keyboardDidAppear(notification)
|
|
72
|
+
} else {
|
|
73
|
+
self.keyboardDidDisappear(notification)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
keyboardDidTask = task
|
|
78
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + UIUtils.nextFrame, execute: task)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
36
82
|
var tag: NSNumber = -1
|
|
37
|
-
|
|
83
|
+
// manual did events
|
|
84
|
+
var notification: Notification?
|
|
85
|
+
var keyboardDidTask: DispatchWorkItem?
|
|
38
86
|
|
|
39
87
|
@objc public init(
|
|
40
88
|
handler: @escaping (NSString, NSNumber, NSNumber, NSNumber, NSNumber) -> Void,
|
package/package.json
CHANGED