Я использовал этот код, чтобы определить размер клавиатуры:
- (void)keyboardWillChange:(NSNotification *)notification {
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}
Я запускаю это в симуляторе.
Проблема в том, что с iOS 8 это не даст правильного значения, если предложения клавиатуры активны или если я их нажимаю, я получаю другие (неверные) значения.
Как я могу получить точный размер клавиатуры, включая варианты клавиатуры?
ios
objective-c
cocoa-touch
keyboard
ios8
Эли Брагинский
источник
источник
keyboardFrameBeginRect
в местные координаты.Ответы:
Использовать
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
источник
С появлением пользовательских клавиатур в iOS эта проблема становится немного сложнее.
Короче говоря, UIKeyboardWillShowNotification может вызываться несколько раз с помощью пользовательских реализаций клавиатуры:
Чтобы правильно обрабатывать эти сценарии в одной строке кода, вам необходимо:
Зарегистрируйте наблюдателей против уведомлений UIKeyboardWillShowNotification и UIKeyboardWillHideNotification :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Создайте глобальную переменную для отслеживания текущей высоты клавиатуры:
CGFloat _currentKeyboardHeight = 0.0f;
Реализуйте keyboardWillShow, чтобы реагировать на текущее изменение высоты клавиатуры:
- (void)keyboardWillShow:(NSNotification*)notification { NSDictionary *info = [notification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; CGFloat deltaHeight = kbSize.height - _currentKeyboardHeight; // Write code to adjust views accordingly using deltaHeight _currentKeyboardHeight = kbSize.height; }
ПРИМЕЧАНИЕ. Вы можете захотеть анимировать смещение видов. Информация о словаре содержит значение заклиненного по UIKeyboardAnimationDurationUserInfoKey . Это значение можно использовать для анимации ваших изменений с той же скоростью, что и отображаемая клавиатура.
Реализация keyboardWillHide на вход сброса _currentKeyboardHeight и реагировать на клавиатуру увольнения:
- (void)keyboardWillHide:(NSNotification*)notification { NSDictionary *info = [notification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; // Write code to adjust views accordingly using kbSize.height _currentKeyboardHeight = 0.0f; }
источник
KEYBOARD BEGIN RECT: (0.0, 375.0, 667.0, 162.0) ... KEYBOARD END RECT: (0.0, 213.0, 667.0, 162.0)
У меня тоже была эта проблема, пока я не наткнулся на этот StackOverflow статью на :
Преобразовать UIKeyboardFrameEndUserInfoKey
Это показывает вам, как использовать
convertRect
функцию, чтобы преобразовать размер клавиатуры во что-то полезное, но с ориентацией экрана.NSDictionary* d = [notification userInfo]; CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue]; r = [myView convertRect:r fromView:nil];
Раньше у меня было приложение для iPad, которое использовал,
UIKeyboardFrameEndUserInfoKey
но не использовалconvertRect
, и оно работало нормально.Но с iOS 8 он больше не работал должным образом. Внезапно он сообщил, что моя клавиатура, работающая на iPad в ландшафтном режиме, имеет высоту 1024 пикселя .
Итак, теперь, с iOS 8, вам необходимо использовать эту
convertRect
функцию.источник
Аналогично решению dgangsta, написанному на Swift 2.0:
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardWillShow(notification: NSNotification) { guard let kbSizeValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return } animateToKeyboardHeight(kbSizeValue.CGRectValue().height, duration: kbDurationNumber.doubleValue) } func keyboardWillHide(notification: NSNotification) { guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return } animateToKeyboardHeight(0, duration: kbDurationNumber.doubleValue) } func animateToKeyboardHeight(kbHeight: CGFloat, duration: Double) { // your custom code here }
источник
Я делаю
extension
дляUIViewController
extension UIViewController { func keyboardWillChangeFrameNotification(notification: NSNotification, scrollBottomConstant: NSLayoutConstraint) { let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber let keyboardBeginFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue() let keyboardEndFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue() let screenHeight = UIScreen.mainScreen().bounds.height let isBeginOrEnd = keyboardBeginFrame.origin.y == screenHeight || keyboardEndFrame.origin.y == screenHeight let heightOffset = keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y - (isBeginOrEnd ? bottomLayoutGuide.length : 0) UIView.animateWithDuration(duration.doubleValue, delay: 0, options: UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)), animations: { () in scrollBottomConstant.constant = scrollBottomConstant.constant + heightOffset self.view.layoutIfNeeded() }, completion: nil ) } }
Вы можете использовать это так:
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChangeFrameNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil) } ... deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardWillChangeFrameNotification(notification: NSNotification) { self.keyboardWillChangeFrameNotification(notification, scrollBottomConstant: inputContainerBottom) // Write more to here if you want. }
источник
inputContainerBottom
?Бывают случаи, когда разработчикам необходимо знать высоту клавиатуры до того, как она будет отображена, что позволяет им предварительно настроить интерфейс соответствующим образом.
Если это так, вот подробное описание:
Это включает в себя панель быстрого набора вверху, поскольку она по умолчанию включена во всех текущих версиях iOS.
Вот настройка уведомлений Swift 3, которую я использовал, чтобы проверить это, если кому-то это нужно:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil) } func keyboardWillShow(notification: NSNotification) { guard let keyboardSize = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return } print("\(keyboardSize)") }
источник
Только одна строка для swift:
let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size
UIKeyboardFrameEndUserInfoKey
всегда хранитNSValue
, поэтому не нужно его проверять.источник
Я заметил проблему при переключении между клавиатурой по умолчанию и настраиваемой (
UIPickerView
) клавиатурой - настраиваемая клавиатура показывала высоту 253 вместо 162 после переключения с клавиатуры по умолчанию.В этом случае работала настройка
autocorrectionType = UITextAutocorrectionTypeNo;
поля ввода с помощью настраиваемой клавиатуры.Проблема возникла только в iOS 8 (проверено только на симуляторе). Этого не происходит в iOS 9 (симулятор или устройство).
источник
В Swift не в одну строчку ...
self.keyboardDidShowObserver = NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { (notification) in if let userInfo = notification.userInfo, let keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { let keyboardRect = keyboardFrameValue.CGRectValue() // keyboardRect.height gives the height of the keyboard // your additional code here... } })
источник
[notificationCenter addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification * _Nonnull note) { float keyboardHeight = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; }];
источник