From 40581d791ad0a539965a3ec9cc5fb2bf0dfa39b6 Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Tue, 7 Apr 2026 11:19:39 -0300 Subject: [PATCH] fix: update keyboard notification handling for Swift concurrency Keep snackbar keyboard animations on the main actor and read UIKit keyboard values using the expected notification payload types. Made-with: Cursor --- .../LCEssentials/Message/LCSnackBarView.swift | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/Sources/LCEssentials/Message/LCSnackBarView.swift b/Sources/LCEssentials/Message/LCSnackBarView.swift index 76fc08f..8427cb2 100644 --- a/Sources/LCEssentials/Message/LCSnackBarView.swift +++ b/Sources/LCEssentials/Message/LCSnackBarView.swift @@ -233,53 +233,36 @@ public extension LCSnackBarView { /// Handles the `keyboardWillShowNotification` to adjust the snackbar's position. /// - Parameter notification: The `Notification` object containing keyboard information. - @objc private func keyboardWillShow(_ notification: Notification?) -> Void { - - if let info = notification?.userInfo { - - systemKeyboardVisible = true - // - let curveUserInfoKey = UIResponder.keyboardAnimationCurveUserInfoKey - let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey - let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey - // - var animationCurve: UIView.AnimationOptions = .curveEaseOut - var animationDuration: TimeInterval = 0.25 - var height:CGFloat = 0.0 - - // Getting keyboard animation. - if let curve = info[curveUserInfoKey] as? UIView.AnimationOptions { - animationCurve = curve - } - - // Getting keyboard animation duration - if let duration = info[durationUserInfoKey] as? TimeInterval { - animationDuration = duration - } - - // Getting UIKeyboardSize. - if let kbFrame = info[frameEndUserInfoKey] as? CGRect { - height = kbFrame.size.height - } - - DispatchQueue.main.async { [weak self] in - UIView.animate(withDuration: animationDuration, - delay: 0, - options: animationCurve, - animations: { - self?.frame.origin.y += height - }) - } + @MainActor + @objc private func keyboardWillShow(_ notification: Notification?) { + guard let info = notification?.userInfo else { return } + + systemKeyboardVisible = true + + let animationCurveRaw = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue + ?? UInt(UIView.AnimationCurve.easeOut.rawValue) + let animationDuration = (info[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue + ?? 0.25 + let keyboardFrame = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue + ?? .zero + let height = keyboardFrame.height + let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw << 16) + + UIView.animate( + withDuration: animationDuration, + delay: 0, + options: animationCurve + ) { [weak self] in + self?.frame.origin.y += height } } /// Handles the `keyboardWillHideNotification`. /// - Parameter notification: The `Notification` object. - @objc private func keyboardWillHide(_ notification: Notification?) -> Void { - DispatchQueue.main.async { [weak self] in - self?.systemKeyboardVisible = false - // keyboard is hidded - } + @MainActor + @objc private func keyboardWillHide(_ notification: Notification?) { + systemKeyboardVisible = false + // keyboard is hidded } /// Updates the snackbar's style properties, such as width and corner radius, based on `_style`.