Я знаю, что это должно произойти, но это вызывает у меня проблемы, которые я не знаю, как исправить.keyboardWillShow вызывается для клавиатур других приложений
Я хочу переместить мой взгляд вверх, когда клавиатура покажет, так что мои текстовые поля остаются видимыми.
В моих текстовых полях есть цифровые клавиатуры.
Я использую уведомления и keyboardWillShow/Hide
, чтобы переместить мой просмотр вверх/вниз, когда выбрано текстовое поле.
Теперь предположим, что я нажимаю на текстовое поле, а затем переключаюсь на другое приложение, использующее другую клавиатуру (а не цифровую клавиатуру). keyboardWillShow
вызывается с размером неправильной клавиатуры (другой из другого приложения), и мое представление перемещено неправильно (оно вообще не должно двигаться). Поэтому, когда я возвращаюсь к своему приложению, мое мнение не в том месте, и клавиатура даже не отображается, а затем вызывается keyboardWillHide
, и представление возвращается на место (из ниоткуда). Но keyboardWillShow
не следует даже вызывать для другого приложения.
Я удаляю уведомления на viewWillDisappear
, но это все еще происходит ... может быть, keyboardWillShow
вызывается для других приложений до того, как viewWillDisappear
вызывается для моего?
Вот мой код:
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
})
}
}
Edit: Как @JasonNam отметил в своем ответе, viewWillDisappear не дозвонились при переключении приложений, так что мне пришлось добавить applicationWillResignActive
уведомление, чтобы удалить уведомления о клавиатуре и уведомление applicationDidBecomeActive
, чтобы добавить их обратно.
Редактировать 2: Решение @ sahara108 выглядит чище, и я не вижу недостатков. Мне просто нужно было проверить UIApplication.sharedApplication().applicationState == .Active
, прежде чем делать что-либо в клавиатуреWillShow.
Одна большая проблема в вашем коде. Вы добавляете 'self' в качестве наблюдателя уведомлений, но пытаетесь удалить' self.view'. Вам нужно удалить 'self'. – rmaddy
К сожалению, я изначально удалял 'self', но я заметил эту проблему и начал пробовать всевозможные сумасшедшие вещи, включая удаление наблюдателя из' self.view' вместо 'self', после чего я забыл изменить эту часть, когда Я разместил здесь код. Однако проблема остается в любом случае. И, озираясь, я узнал, что, по-видимому, это должно произойти ... но я не хочу этого, и я не знаю, что делать. – dbmrq