Użyłem tego kodu, aby określić, jaki jest rozmiar klawiatury:
- (void)keyboardWillChange:(NSNotification *)notification {
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}
Uruchamiam to w symulatorze.
Problem polega na tym, że iOS 8 nie da prawidłowej wartości, jeśli sugestie dotyczące klawiatury są włączone lub jeśli je popchnę, otrzymam inne (nieprawidłowe) wartości.
Jak uzyskać dokładny rozmiar klawiatury, w tym sugestie dotyczące klawiatury?
ios
objective-c
cocoa-touch
keyboard
ios8
Eli Braginskiy
źródło
źródło
keyboardFrameBeginRect
na współrzędne lokalne.Odpowiedzi:
Posługiwać się
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
źródło
Wraz z wprowadzeniem niestandardowych klawiatur w systemie iOS problem ten staje się nieco bardziej złożony.
Krótko mówiąc, UIKeyboardWillShowNotification można wywoływać wiele razy przez niestandardowe implementacje klawiatury:
Aby poprawnie obsłużyć te scenariusze w jednej linii kodu, musisz:
Zarejestruj obserwatorów w powiadomieniach UIKeyboardWillShowNotification i UIKeyboardWillHideNotification :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Utwórz zmienną globalną, aby śledzić aktualną wysokość klawiatury:
CGFloat _currentKeyboardHeight = 0.0f;
Zaimplementuj keyboardWillShow, aby zareagować na bieżącą zmianę wysokości klawiatury:
- (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; }
UWAGA: Możesz chcieć animować przesunięcie widoków. Informacji słownik zawiera wartość wprowadzonego przez UIKeyboardAnimationDurationUserInfoKey . Ta wartość może służyć do animowania zmian z taką samą prędkością, jak wyświetlana jest klawiatura.
Zaimplementuj klawiaturęWillHide do resetowania _currentKeyboardHeight i zareaguj na odrzucenie klawiatury:
- (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; }
źródło
KEYBOARD BEGIN RECT: (0.0, 375.0, 667.0, 162.0) ... KEYBOARD END RECT: (0.0, 213.0, 667.0, 162.0)
Miałem też ten problem, dopóki nie natknąłem się na ten artykuł StackOverflow :
Konwertuj UIKeyboardFrameEndUserInfoKey
To pokazuje, jak używać tej
convertRect
funkcji, aby przekonwertować rozmiar klawiatury na coś użytecznego, ale z orientacją ekranu.NSDictionary* d = [notification userInfo]; CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue]; r = [myView convertRect:r fromView:nil];
Wcześniej miałem aplikację na iPada, która była używana,
UIKeyboardFrameEndUserInfoKey
ale nie korzystałaconvertRect
, i działała dobrze.Ale z iOS 8 nie działało już poprawnie. Nagle informował, że moja klawiatura działająca na iPadzie w trybie poziomym miała 1024 piksele wysokości .
Więc teraz, w iOS 8, ważne jest, abyś używał tej
convertRect
funkcji.źródło
Podobne do rozwiązania dgangsta napisanego w 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 }
źródło
Robię
extension
dlaUIViewController
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 ) } }
Możesz użyć w ten sposób:
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. }
źródło
inputContainerBottom
?Są chwile, kiedy programiści muszą znać wysokość klawiatury, zanim zostanie faktycznie wyświetlona, co pozwala im odpowiednio przygotować interfejs.
W takim przypadku oto szczegółowa specyfikacja:
Obejmuje to pasek szybkiego pisania u góry, ponieważ jest on domyślnie włączony we wszystkich aktualnych wersjach iOS.
Oto szybka konfiguracja powiadomień 3, której użyłem do przetestowania, jeśli ktoś tego potrzebuje:
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)") }
źródło
Tylko jeden ciąg do szybkiego:
let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size
UIKeyboardFrameEndUserInfoKey
zawsze przechowujeNSValue
, więc nie musisz tego sprawdzać.źródło
Zauważyłem problem wyświetlający się podczas przełączania między klawiaturą domyślną a niestandardową (
UIPickerView
) - niestandardowa klawiatura pokazywałaby wysokość 253 zamiast 162 po przełączeniu z klawiatury domyślnej.W tym przypadku zadziałało ustawienie
autocorrectionType = UITextAutocorrectionTypeNo;
pola wprowadzania za pomocą niestandardowej klawiatury.Problem wystąpił tylko w iOS 8 (testowano tylko na symulatorze). Nie występuje w iOS 9 (symulator lub urządzenie).
źródło
W Swift, nie w jednej linii ...
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... } })
źródło
[notificationCenter addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification * _Nonnull note) { float keyboardHeight = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; }];
źródło