Reputation: 1316
My app monitors changes to the keyboard to animate specific parts of the UI using UIKeyboardWillShow
and UIKeyboardWillHide
notifications.
The issue I am having is that when I switch from the Messages app with the keyboard shown to my app using the app switcher (in a state where the keyboard is not required), it will trigger the UIKeyboardWillShow
notification and then the UIKeyboardWillHide
notification which is resulting in my UI jumping up and down a bit.
Is there a way to only listen to keyboard notifications for your own app?
ViewWillAppear
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChange:", name: UIKeyboardWillChangeFrameNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
ViewWillDisappear
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillChangeFrameNotification, object: nil)
Upvotes: 1
Views: 536
Reputation: 512
I came across this problem today. What I ended up doing was adding observers to detect when the app enters and leaves background. If it enters background then remove the keyboard observer else add the keyboard observers. Something like this... I'm sure there's a better way, but this worked for me. Hope this helps.
override func viewDidLoad() {
super.viewDidLoad()
registerForPreviewing(with: self, sourceView: collectionView)
addApplicationStateObservers()
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addKeyboardObservers()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
removeKeyboardObservers()
}
deinit {
removeApplicationStateObservers()
removeKeyboardObservers()
}
func applicationIsActive() {
let delay = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: delay) {
self.addKeyboardObservers()
}
}
// Observers
// Application state observers were add to handle edge case scenario where if user is playing a video in expanded pip view on iPhone, if user switchs to another app with keyboard then switch back, the video will disppears. Our app removes and re-adds observer as user enter and exit the app.
func addApplicationStateObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(applicationIsActive), name: .UIApplicationDidBecomeActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(removeKeyboardObservers), name: .UIApplicationDidEnterBackground, object: nil)
}
func removeApplicationStateObservers() {
NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIApplicationDidEnterBackground, object: nil)
}
func addKeyboardObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden), name: .UIKeyboardWillHide, object: nil)
}
func removeKeyboardObservers() {
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
Upvotes: 0
Reputation: 395
Any code?
Do you observe keyboard entire your app or only in a viewcontroller
?
Whenever you don't want to listen the changes you can removeObserver
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] removeObserver:yourClass name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:yourClass name:UIKeyboardWillHideNotification object:nil];
}
But be careful, you need to use NSNotificationCenter
properly.
Upvotes: 1