2016-03-16 5 views
0

Мне нужно переместить UIView, как только клавиатура станет видимой. Но проблема, с которой я сейчас сталкиваюсь, заключается в том, что мой UIKeyboardWillShowNotification называется три раза, когда я использую пользовательскую клавиатуру (например, SwiftKey), что приводит к плохой анимации.
Есть ли способ обработать только последнее уведомление? Я мог бы легко уклониться от первого, потому что высота равна 0, но вторая выглядит как допустимая высота, и я не нахожу ответа о том, как это решить.
Вот то, что я до сих пор:UIKeyboardWillShowNotification называется три раза

override func viewDidLoad() { 
    super.viewDidLoad() 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillAppear:", name: UIKeyboardWillShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillDisappear:", name: UIKeyboardWillHideNotification, object: nil) 
} 

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

    NSNotificationCenter.defaultCenter().removeObserver(self) 
} 

func keyboardWillAppear(notification: NSNotification){ 
    print("keyboard appear") 
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() { 
     print("with height: \(keyboardSize.height)") 
     if keyboardSize.height == 0.0 { 
      return 
     } 
     self.txtViewBottomSpace.constant = keyboardSize.height 
     UIView.animateWithDuration(0.4, animations: {() -> Void in 
      self.view.layoutIfNeeded() 
     }) 
    } 
} 

func keyboardWillDisappear(notification: NSNotification){ 
    print("Keyboard disappear") 
    self.txtViewBottomSpace.constant = 0.0 
    UIView.animateWithDuration(0.4, animations: {() -> Void in 
     self.view.layoutIfNeeded() 
    }) 
} 

Мой выход Log является:

клавиатуры появляются
с высоты: 0,0
клавиатура появляется
с высоты: 216,0
клавиатуры
с высотой: 258.0
Клавиатура исчезает

Итак, есть ли способ обработать третье уведомление и «игнорировать» первые два?

+0

Добавить команду if, чтобы проверить, не работает ли ваша высота клавиатуры = 258.0? –

+0

Ну, не каждая клавиатура имеет такую ​​же высоту, поэтому я не могу просто проверить 258.0 –

ответ

0

Я предлагаю заменить статическую продолжительность анимации (0.4) на продолжительность анимации клавиатуры, возвращенную в словаре userInfo уведомления под номером UIKeyboardAnimationDurationUserInfoKey. Таким образом, ваша анимация будет синхронизироваться с анимацией клавиатуры. Вы также можете получить кривую анимации, используемую клавиатурой, с помощью клавиши UIKeyboardAnimationCurveUserInfoKey.

func keyboardWillAppear(notification: NSNotification){ 
    print("keyboard appear") 
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() { 
     let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue; 
     print("with height: \(keyboardSize.height)") 
     if keyboardSize.height == 0.0 { 
      return 
     } 
     self.txtViewBottomSpace.constant = keyboardSize.height 
     UIView.animateWithDuration(animationDuration!, delay: 0.0, options: .BeginFromCurrentState, animations: {() -> Void in 
      self.view.layoutIfNeeded() 
     }) 
    } 
} 

func keyboardWillDisappear(notification: NSNotification){ 
    print("Keyboard disappear") 
    let animationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue; 
    self.txtViewBottomSpace.constant = 0.0 
     UIView.animateWithDuration(animationDuration!, delay: 0.0, options: .BeginFromCurrentState, animations: {() -> Void in 
     self.view.layoutIfNeeded() 
    }) 
} 
+0

Спасибо за предложение о продолжительности. Но проблема остается прежней, когда на клавиатуре появляется все «прыгает» на новое место, но нет гладкой анимации, потому что метод вызывается несколько раз :( –

+0

Попробуйте добавить параметр .BeginFromCurrentState в свою анимацию. с добавленной опцией. – lorenzoliveto

+0

В альтернативе вы можете проверить, если ваш self.txtViewBottomSpace.constant равен 0, чтобы начать анимацию. – lorenzoliveto

0

Изменение имени уведомления UIKeyboardDidShowNotification и UIKeyboardDidHideNotification затем решить проблему

override func viewDidLoad() { 
    super.viewDidLoad() 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillAppear:", name: UIKeyboardDidShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillDisappear:", name: UIKeyboardDidHideNotification, object: nil) 
} 

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

    NSNotificationCenter.defaultCenter().removeObserver(self) 
} 

func keyboardWillAppear(notification: NSNotification){ 
    print("keyboard appear") 
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() { 
     print("with height: \(keyboardSize.height)") 
     if keyboardSize.height == 0.0 { 
      return 
     } 
     self.txtViewBottomSpace.constant = keyboardSize.height 
     UIView.animateWithDuration(0.4, animations: {() -> Void in 
      self.view.layoutIfNeeded() 
     }) 
    } 
} 

func keyboardWillDisappear(notification: NSNotification){ 
    print("Keyboard disappear") 
    self.txtViewBottomSpace.constant = 0.0 
    UIView.animateWithDuration(0.4, animations: {() -> Void in 
     self.view.layoutIfNeeded() 
    }) 
} 
+0

Спасибо за ваше предложение, но когда я меняю уведомление на DidAppear, он вызывается, когда клавиатура уже видна, поэтому я не могу сделать анимацию представления, движущегося вверх с помощью клавиатуры. –

0

Причина этого заключается в том, потому что клавиатура может иметь различные размеры, особенно те, третьих лиц. Таким образом, первое уведомление, которое вы получите, всегда будет для системной высоты по умолчанию, и любое, которое вы получите после этого, будет включать в себя новые высоты стороннего расширения клавиатуры, если оно загружено. Чтобы обойти это, в вашем методе, который обрабатывает уведомление, вам нужно получить высоту изначально, а затем установить это как высоту по умолчанию (я думаю, 226). Затем установите переменную на эту первую высоту, а затем для результирующих вызовов метода уведомления вы можете проверить, больше ли высота нового размера, чем исходная высота, и если это вы можете найти дельту, а затем соответствующим образом скорректировать свои фреймы.

0

Установите все поля ниже, чтобы НЕТ, разрешить эту проблему.

Capitalizaion: None 
Correction: No 
Smart Dashes: No 
Smart insert: No 
Smart Quote: No 
Spell Checking: No 
Смежные вопросы