2016-03-22 5 views
0

У меня есть пользовательская клавиатура iOS, которая меняет высоту при ее повороте.Неверная клавиатура Высота расширения после вращения

Мой код работает отлично 95% раз ... Но в некоторых случаях (см. Ниже) высота не изменяется при повороте в альбомной ориентации - сохраняется высота портрета.

Проблема может быть воспроизведена с этим (почти) минимальным кодом - создать новую цель Keyboard Extension и скопировать этот код KeyboardViewController:

class KeyboardViewController: UIInputViewController { 
    private var orangeView = UIView() 
    private var heightConstraint: NSLayoutConstraint! 
    @IBOutlet var nextKeyboardButton: UIButton! 

    override func updateViewConstraints() { 
     super.updateViewConstraints() 
     let screenSize = UIScreen.mainScreen().bounds.size 
     let screenH = screenSize.height 
     let screenW = screenSize.width 
     let isLandscape = !(self.view.frame.size.width == screenW * ((screenW < screenH) ? 1 : 0) + screenH * ((screenW > screenH) ? 1 : 0)) 
     let desiredHeight: CGFloat = isLandscape ? 193 : 252 
     if heightConstraint.constant != desiredHeight { 
      heightConstraint!.constant = desiredHeight 
      orangeView.frame = CGRect(x: 0, y: 0, width: screenW, height: isLandscape ? 193 : 252) 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     nextKeyboardButton = UIButton(type: .System) 
     nextKeyboardButton.setTitle("Next Keyboard", forState: .Normal) 
     nextKeyboardButton.sizeToFit() 
     nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = false 
     nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside) 
     heightConstraint = NSLayoutConstraint(item:self.inputView!, attribute:.Height, relatedBy:.Equal, toItem:nil, attribute:.NotAnAttribute, multiplier: 0.0, constant: 0) //preparing heightConstraint 
     heightConstraint?.priority = 999 
     orangeView.backgroundColor = UIColor.orangeColor() 
     view.addSubview(orangeView) 
     view.addSubview(self.nextKeyboardButton) 
     let nextKeyboardButtonLeftSideConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 0.0) 
     let nextKeyboardButtonBottomConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0) 
     view.addConstraints([nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint]) 
    } 

    override func viewWillAppear(animated: Bool) { 
     if self.view.constraints.filter({c in c == self.heightConstraint}).isEmpty { 
      self.view.addConstraint(heightConstraint) 
     } 
     view.setNeedsUpdateConstraints() //ensures that updateViewConstraints always gets called at least once 
     super.viewWillAppear(animated) 
    } 
} 

Для получения дополнительной информации о том, как это работает см this и this ответа.

При запуске клавиатуры это вероятно, будет работать нормально - это немного выше, и после поворота вида оранжевого охватывает всю клавиатуру:

enter image description here

Однако вы можете также получить это (портретную высоту сохраняется после поворота):

enter image description here

Действия по воспроизведению isue (с кодом выше):

  1. Открыть клавиатуры в Messages приложение, поворот пейзаж и обратно
  2. Если вы не видите вопрос убить сообщения приложение нажмите кнопку (поездки 2x -> сообщения мазковые вверх)
  3. Open сообщения снова, вращать ландшафт и обратно
  4. Вам может понадобиться повторить шаги 1-3 несколько раз, чтобы этот вопрос (как правило, не более 2-4 раз)

Что я знаю:

  • Если вы видите проблему вы будете держать Seing, пока клавиатура не будет скрыт и повторно отображается
  • Если вы видите выпуск скрыть и повторно отобразить клавиатуру жгутов же приложение - вопрос всегда disapears
  • проблема может появиться снова только после убийства и перезапуска приложения хостинга
  • Debuger показывает, что heightConstraint!.constant является 193 но оба view.frame.height и view.window?.frame.height все еще 253 (изменение кадра непосредственно не исправить)

То, что я пробовал:

  • Вместо того, чтобы просто установив ограничение heightConstraint!.constant = desiredHeight сначала удалить его из view, установить новое значение, а затем повторно добавить его
  • Я проверил, что heightConstraint!.constant всегда изменяется когда это должно быть

Как исправить или обмануть эту проблему? Должно быть решение, потому что у SwiftKey нет этой проблемы.

ответ

1

Я столкнулся с аналогичной проблемой с расширением клавиатуры - на моделях iPhone 6+, он всегда не удалось правильно установить его высоту на поворотах на первый время клавиатура вызывалась в приложении, а иногда и на iPhone 6 и другие модели iPhone.

В итоге я нашел решение, хотя оно имеет свои недостатки.

Во-первых, в документации говорится, что

В прошивкой 8.0, вы можете настроить ВЫСОТА специальной клавиатуры в любое время после того, как его основной вид сначала рисует на экране.

Вы устанавливаете ограничение по высоте в -[UIViewController viewWillAppear:], что при строгой интерпретации документации слишком рано. Если вы установите его в -[UIViewController viewDidAppear:], проблема, которую вы в настоящее время должны решить, должна быть решена.

Однако вы можете обнаружить, что ваша регулировка высоты визуально сотрясается, как это происходит после появления клавиатуры.

Я понятия не имею, как SwiftKey удается установить их высоту (по-видимому) до появления на клавиатуре и избежать этой проблемы.

+0

Спасибо! Похоже, добавление ограничения в 'viewDidAppear' решает проблему. Что касается indtoduced проблемы с визуально jarring высота адъюции: на основе моего тестирования на iOS 9 первое появление в приложении всегда ОК, любой подпоследовательность jarring независимо от того, добавлено ограничение в 'viewWillAppear' или' viewDidAppear'. На iOS 8 есть разница, но не такая уж большая ... У вас есть отличный опыт? – drasto