Skip to content

Instantly share code, notes, and snippets.

@CypherPoet
Last active October 29, 2019 08:25
Show Gist options
  • Save CypherPoet/24eb4f1aac4ac31d6cd9ba05a7e707db to your computer and use it in GitHub Desktop.
Save CypherPoet/24eb4f1aac4ac31d6cd9ba05a7e707db to your computer and use it in GitHub Desktop.
Keyboard follower implemented as an ObservableObject using Swift Combine Publishers
import Combine
import Foundation
import UIKit
final class KeyboardFollower: ObservableObject {
private var subscriptions = Set<AnyCancellable>()
@Published var keyboardHeight: CGFloat = 0.0
@Published var isKeyboardVisible: Bool = false
var keyboardChangeFrames: AnyPublisher<(begin: CGRect, end: CGRect), Never> {
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { notification in
guard
let userInfo = notification.userInfo,
let beginFrame = userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect,
let endFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
else { return nil }
return (begin: beginFrame, end: endFrame)
}
.eraseToAnyPublisher()
}
init() {
keyboardChangeFrames
.receive(on: RunLoop.main)
.map { frames in
frames.begin.minY > frames.end.minY
}
.assign(to: \.isKeyboardVisible, on: self)
.store(in: &subscriptions)
keyboardChangeFrames
.receive(on: RunLoop.main)
.map { frames in
self.isKeyboardVisible ? frames.end.height : 0.0
}
.assign(to: \.keyboardHeight, on: self)
.store(in: &subscriptions)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment