KeyboardWillShow invoked for other application keyboards

I know that this should happen, but it causes me problems that I don’t know how to fix.

I want to move my view when it is displayed on the keyboard so that my text fields remain visible.

My text fields have numeric keypads.

I use notifications and keyboardWillShow/Hideto move my view up / down when I select a text box.

Now suppose I click on a text field and then switch to another application using a different keyboard (and not a numeric keypad). keyboardWillShowgets called with the size of the wrong keyboard (another from another application), and my view moves for the wrong amount (it should not move at all). Therefore, when I return to my application, my opinion is in the wrong place, and the keyboard does not even appear, and then it is called keyboardWillHide, and the view moves to the place (out of nowhere). But you keyboardWillShowdo not even need to call for another application.

I delete notifications in viewWillDisappear, but this is still happening ... maybe it is being keyboardWillShowcalled for other applications before being viewWillDisappearcalled for mine?

Here is my code:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
    for subview in self.view.subviews {
        if subview.isKindOfClass(UITextField) {
            let textField = subview as! UITextField
            textField.addTarget(self, action: "textFieldDidReturn:", forControlEvents: UIControlEvents.EditingDidEndOnExit)
            textField.addTarget(self, action: "textFieldDidBeginEditing:", forControlEvents: UIControlEvents.EditingDidBegin)
        }
    }
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    self.keyboardIsShowing = true
    if let info = notification.userInfo {
       self.keyboardFrame = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
       self.arrangeViewOffsetFromKeyboard()
    }
}

func keyboardWillHide(notification: NSNotification) {
    self.keyboardIsShowing = false
    self.returnViewToInitialFrame()
}

func arrangeViewOffsetFromKeyboard() {
    if let textField = activeTextField {
        let theApp: UIApplication = UIApplication.sharedApplication()
        let windowView: UIView? = theApp.delegate!.window!
        let textFieldLowerPoint = CGPoint(x: textField.frame.origin.x, y: textField.frame.origin.y + textField.frame.size.height)
        let convertedTextFieldLowerPoint = textField.superview!.convertPoint(textFieldLowerPoint, toView: windowView)
        let targetTextFieldLowerPoint = CGPoint(x: textField.frame.origin.x, y: self.keyboardFrame.origin.y)
        let targetPointOffset = targetTextFieldLowerPoint.y - convertedTextFieldLowerPoint.y
        let adjustedViewFrameCenter = CGPoint(x: self.view.center.x, y: self.view.center.y + targetPointOffset)
        print(targetPointOffset) // When I change to a different app this prints the wrong value… but none of this should even get called.
        if targetPointOffset < 0 {
            UIView.animateWithDuration(0.3, animations: {
                self.view.center = adjustedViewFrameCenter
            })
        }
    }
}

func returnViewToInitialFrame() {
    let initialViewRect = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height)
    if !CGRectEqualToRect(initialViewRect, self.view.frame) {
        UIView.animateWithDuration(0.2, animations: {
            self.view.frame = initialViewRect
        })
    }
}

: @JasonNam, viewWillDisappear , applicationWillResignActive, applicationDidBecomeActive, .


2: @sahara108 , . UIApplication.sharedApplication().applicationState == .Active, - WillShow.

+5
7

, textField keyboardWillShown. , .

func keyboardWillShow(notification: NSNotification) {
    if !myTextField.isFirstResponder() {
        return
    }
    self.keyboardIsShowing = true
    if let info = notification.userInfo {
       self.keyboardFrame = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
       self.arrangeViewOffsetFromKeyboard()
    }
}

UPDATE: Responder, , UIApplication.shareApplication().applicationSate == .Active

+7

iOS 9+:

NSNotification, , :

UIKeyboardIsLocalUserInfoKey - NSNumber, , , .

(, , OP):

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
    return UIApplication.shared.applicationState == .active
}

, .

+4

, :

- (void)handleKeyboardWillShowNotification:(NSNotification *)notifaction{
    if([UIApplication sharedApplication].applicationState != UIApplicationStateActive){
        return;
    }
    //your code below...
}
+1

: viewWillDisappear:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    let notificationCenter = NSNotificationCenter.defaultCenter()
    notificationCenter.removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    notificationCenter.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
0

UIApplicationDidEnterBackgroundNotification UIApplicationDidBecomeActiveNotification. , , - .

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationBecomeActive", name: UIApplicationDidBecomeActiveNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationDidEnterBackground", name: UIApplicationDidEnterBackgroundNotification, object: nil)
}

func applicationBecomeActive()
{
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}

func applicationDidEnterBackground()
{
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
0

, , - keyboardWillShow. UIView ( ), , , - , - . , , 2 iOS 9.

0

, , , - firstResponder.

:

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification,object: nil)

@objc func keyboardWillShow(_ notification: Notification) {
    if storeNameTextField.isFirstResponder || methodTextField.isFirstResponder || amountTextField.isFirstResponder || dateTextField.isFirstResponder || categoryTextField.isFirstResponder {
        if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            let keyboardRectangle = keyboardFrame.cgRectValue
            let keyboardHeight = keyboardRectangle.height
            self.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight - 22, right: 0)
        }
    }
}
0

Source: https://habr.com/ru/post/1621213/


All Articles