Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ios/animations/KeyboardAnimation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ public class KeyboardAnimation: KeyboardAnimationProtocol {
// constructor variables
let fromValue: Double
let toValue: Double
let duration: Double
let speed: Double
let timestamp: CFTimeInterval

init(fromValue: Double, toValue: Double, animation: CAMediaTiming) {
init(fromValue: Double, toValue: Double, animation: CAMediaTiming, duration: Double) {
self.fromValue = fromValue
self.toValue = toValue
self.animation = animation
self.duration = duration
speed = Double(animation.speed)
timestamp = CACurrentMediaTime()
}
Expand Down
2 changes: 1 addition & 1 deletion ios/animations/SpringAnimation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public final class SpringAnimation: KeyboardAnimation {
bUnder = 0
}

super.init(fromValue: fromValue, toValue: toValue, animation: animation)
super.init(fromValue: fromValue, toValue: toValue, animation: animation, duration: animation.settlingDuration)
}

// public functions
Expand Down
2 changes: 1 addition & 1 deletion ios/animations/TimingAnimation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public final class TimingAnimation: KeyboardAnimation {
self.p1 = p1
self.p2 = p2

super.init(fromValue: fromValue, toValue: toValue, animation: animation)
super.init(fromValue: fromValue, toValue: toValue, animation: animation, duration: animation.duration)
}

// MARK: public functions
Expand Down
1 change: 1 addition & 0 deletions ios/extensions/Notification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ extension Notification {

extension Notification.Name {
static let shouldIgnoreKeyboardEvents = Notification.Name("shouldIgnoreKeyboardEvents")
static let keyboardDidAppear = Notification.Name("keyboardDidAppear")
}
2 changes: 1 addition & 1 deletion ios/interactive/KeyboardAreaExtender.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class KeyboardAreaExtender: NSObject {
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardDidAppear),
name: UIResponder.keyboardDidShowNotification,
name: .keyboardDidAppear,
object: nil
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,6 @@ public extension KeyboardMovementObserver {
name: UIResponder.keyboardWillShowNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardDidAppear),
name: UIResponder.keyboardDidShowNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardDidDisappear),
name: UIResponder.keyboardDidHideNotification,
object: nil
)
}

@objc func unmount() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
tag = UIResponder.current.reactViewTag
let keyboardHeight = keyboardFrame.cgRectValue.size.height
self.keyboardHeight = keyboardHeight
self.notification = notification
self.duration = duration
didShowDeadline = Date.currentTimeStamp + Int64(duration)

onRequestAnimation()
onEvent("onKeyboardMoveStart", Float(self.keyboardHeight) as NSNumber, 1, duration as NSNumber, tag)
Expand All @@ -30,6 +30,9 @@
guard !UIResponder.isKeyboardPreloading else { return }
let (duration, _) = notification.keyboardMetaData()
tag = UIResponder.current.reactViewTag
self.notification = notification
// when keyboard disappears i
self.notification?.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] = NSValue(cgRect: CGRect(x: 0, y: 0, width: 0, height: 0))

Check failure on line 35 in ios/observers/movement/observer/KeyboardMovementObserver+Listeners.swift

View workflow job for this annotation

GitHub Actions / 🔎 Swift Lint

Line Length Violation: Line should be 120 characters or less; currently it has 132 characters (line_length)
self.duration = duration

onRequestAnimation()
Expand All @@ -44,10 +47,8 @@
@objc func keyboardDidAppear(_ notification: Notification) {
guard !UIResponder.isKeyboardPreloading else { return }

let timestamp = Date.currentTimeStamp
let (duration, frame) = notification.keyboardMetaData()
if let keyboardFrame = frame {
let (position, _) = keyboardTrackingView.view.frameTransitionInWindow
let keyboardHeight = keyboardFrame.cgRectValue.size.height
tag = UIResponder.current.reactViewTag
self.keyboardHeight = keyboardHeight
Expand All @@ -57,9 +58,7 @@
return
}

// if the event is caught in between it's highly likely that it could be a "resize" event
// so we just read actual keyboard frame value in this case
let height = timestamp >= didShowDeadline ? self.keyboardHeight : position - KeyboardAreaExtender.shared.offset
let height = self.keyboardHeight - KeyboardAreaExtender.shared.offset
// always limit progress to the maximum possible value
let progress = min(height / self.keyboardHeight, 1.0)

Expand All @@ -70,6 +69,10 @@
removeKeyboardWatcher()
setupKVObserver()
animation = nil

NotificationCenter.default.post(
name: .keyboardDidAppear, object: notification, userInfo: nil
)
}
}

Expand Down
54 changes: 51 additions & 3 deletions ios/observers/movement/observer/KeyboardMovementObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,30 @@ public class KeyboardMovementObserver: NSObject {
var onCancelAnimation: () -> Void
// progress tracker
var keyboardTrackingView = KeyboardTrackingView()
var animation: KeyboardAnimation?
var animation: KeyboardAnimation? {
didSet {
keyboardDidTask?.cancel()

guard let animation = animation, let notification = notification else {
return
}

let toValue = animation.toValue
let duration = animation.duration

let task = DispatchWorkItem { [weak self] in
guard let self = self else { return }
if toValue > 0 {
self.keyboardDidAppear(notification)
} else {
self.keyboardDidDisappear(notification)
}
}

keyboardDidTask = task
DispatchQueue.main.asyncAfter(deadline: .now() + duration, execute: task)
}
}

var prevKeyboardPosition = 0.0
var displayLink: CADisplayLink!
Expand All @@ -32,9 +55,34 @@ public class KeyboardMovementObserver: NSObject {
set { _keyboardHeight = newValue }
}

var duration = 0
var duration = 0 {
didSet {
keyboardDidTask?.cancel()

guard let notification = notification,
let height = notification.keyboardMetaData().1?.cgRectValue.size.height, duration == 0
else {
return
}

let task = DispatchWorkItem { [weak self] in
guard let self = self else { return }
if height > 0 {
self.keyboardDidAppear(notification)
} else {
self.keyboardDidDisappear(notification)
}
}

keyboardDidTask = task
DispatchQueue.main.asyncAfter(deadline: .now() + UIUtils.nextFrame, execute: task)
}
}

var tag: NSNumber = -1
var didShowDeadline: Int64 = 0
// manual did events
var notification: Notification?
var keyboardDidTask: DispatchWorkItem?

@objc public init(
handler: @escaping (NSString, NSNumber, NSNumber, NSNumber, NSNumber) -> Void,
Expand Down
Loading