UIKeyboardBoundsUserInfoKey jest przestarzały, czego zamiast tego użyć?
Pracuję nad aplikacją na iPada przy użyciu sdk 3.2. Mam do czynienia z uzyskaniem rozmiaru klawiatury, aby zapobiec ukrywaniu się za nią pól tekstowych.
I ' m getting a Warning in Xcode - > UIKeyboardBoundsUserInfoKey is deprecated what should I use instead not to get this warning?
8 answers
Grałem z wcześniej oferowanym rozwiązaniem, ale nadal miałem problemy. Oto co wymyśliłem zamiast tego:
- (void)keyboardWillShow:(NSNotification *)aNotification {
[self moveTextViewForKeyboard:aNotification up:YES];
}
- (void)keyboardWillHide:(NSNotification *)aNotification {
[self moveTextViewForKeyboard:aNotification up:NO];
}
- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
NSDictionary* userInfo = [aNotification userInfo];
// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
// Animate up or down
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect newFrame = textView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1);
textView.frame = newFrame;
[UIView commitAnimations];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-16 15:36:46
Z dokumentacji dla UIKeyboardBoundsUserInfoKey
:
[[4]} Apple zaleca wdrożenie wygodnej procedury, takiej jak ta (która może być zaimplementowana jako dodatek do kategoriiKlawisz dla obiektu NSValue zawierającego CGRect, który identyfikuje prostokąt obwiedni klawiatury we współrzędnych okna. Wartość ta jest wystarczająca do uzyskania rozmiaru klawiatury. Jeśli chcesz uzyskać pochodzenie klawiatury na ekranie (przed lub po animacji), użyj wartości uzyskanych ze słownika informacji użytkownika za pomocą stałych UIKeyboardCenterBeginUserInfoKey lub uikeyboardcenterenduserinfokey. zamiast tego użyj klucza UIKeyboardFrameBeginUserInfoKey lub uikeyboardframeenduserinfokey.
UIScreen
):
+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}
Aby odzyskać dopasowane do okna właściwości rozmiaru ramki klawiatury.
Przyjęłam inne podejście, które polega na sprawdzeniu orientacji urządzenia:
CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-02 20:45:58
Wystarczy użyć tego kodu:
//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//instead of Upper line we can use either next line or nextest line.
//NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 06:45:17
Poniższy kod rozwiązuje problem w Jay ' s answer, który zakłada, że UIKeyboardWillShowNotification
nie uruchomi się ponownie, gdy klawiatura jest już obecna.
UIKeyboardWillShowNotification
z nową ramką klawiatury, nawet jeśli klawiatura jest już obecna, co prowadzi do zmniejszenia wysokości self.textView
po raz drugi w oryginalnym kodzie.
To redukuje self.textView
do prawie niczego. Wtedy staje się niemożliwe do odzyskania z tego problem, ponieważ będziemy oczekiwać tylko jednego UIKeyboardWillHideNotification
następnym razem, gdy klawiatura zostanie odrzucona.
Zamiast odejmować / dodawać wysokość do self.textView
w zależności od tego, czy klawiatura jest pokazana/ukryta jak w oryginalnym kodzie, poniższy kod oblicza maksymalną możliwą wysokość dla self.textView
po odjęciu wysokości klawiatury na ekranie.
Zakłada się, że self.textView
ma wypełnić cały widok kontrolera widoku i nie ma innego podglądu, który musi być widoczne.
- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif {
NSDictionary* userInfo = [notif userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrameInWindowsCoordinates;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates];
[self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates
withAnimationDuration:animationDuration
animationCurve:animationCurve];
}
- (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates
withAnimationDuration:(NSTimeInterval)duration
animationCurve:(UIViewAnimationCurve)curve
{
CGRect fullFrame = self.view.frame;
CGRect keyboardFrameInViewCoordinates =
[self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];
// Frame of the keyboard that intersects with the view. When keyboard is
// dismissed, the keyboard frame still has width/height, although the origin
// keeps the keyboard out of the screen.
CGRect keyboardFrameVisibleOnScreen =
CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates);
// Max frame availble for text view. Assign it to the full frame first
CGRect newTextViewFrame = fullFrame;
// Deduct the the height of any keyboard that's visible on screen from
// the height of the text view
newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height;
if (duration)
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
}
// Adjust the size of the text view to the new one
self.textView.frame = newTextViewFrame;
if (duration)
{
[UIView commitAnimations];
}
}
Nie zapomnij również zarejestrować powiadomień klawiatury w viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter];
[notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil];
[notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil];
}
O podzieleniu kodu zmiany rozmiaru na dwie części
Powodem, dla którego kod zmiany rozmiaru textView jest podzielony na dwie części (resizeTextViewWithKeyboardNotification:
i resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
), jest naprawienie innego problemu, gdy klawiatura pozostaje wciśnięta z jednego kontrolera widoku do drugiego (Zobacz Jak wykryć klawiaturę iOS, gdy pozostaje między kontrolerami?).
Ponieważ klawiatura jest system iOS nie generuje żadnych dodatkowych powiadomień z klawiatury, a tym samym nie ma możliwości zmiany rozmiaru textView
na podstawie tych powiadomień z klawiatury.
Powyższy kod (jak również oryginalny kod), który zmienia rozmiar self.textView
będzie działać tylko wtedy, gdy klawiatura zostanie pokazana Po załadowaniu widoku.
Moim rozwiązaniem jest utworzenie singletonu, który przechowuje Ostatnie współrzędne klawiatury, a na - viewDidAppear:
viewController, wywołanie:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Resize the view if there's any keyboard presence before this
// Only call in viewDidAppear as we are unable to convertRect properly
// before view is shown
[self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame]
withAnimationDuration:0
animationCurve:0];
}
UASKeyboard
jest tu mój singleton. Idealnie powinniśmy to wywołać w - viewWillAppear:
, jednak z mojego doświadczenia (przynajmniej na iOS 6), metoda convertRect:fromView:
, którą musimy użyć w resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
, nie konwertuje poprawnie ramki klawiatury na współrzędne widoku, zanim widok będzie w pełni widoczny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:27:45
Po prostu użyj klucza UIKeyboardFrameBeginUserInfoKey
LUB UIKeyboardFrameEndUserInfoKey
zamiast UIKeyboardBoundsUserInfoKey
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-05 07:49:41
@Jason, kodujesz jeśli dobrze, z wyjątkiem jednego punktu.
W tej chwili nic nie animujesz, a Widok po prostu " pop " do nowego rozmiaru.wzrost.
Należy określić stan, z którego ma być animowany. Animacja to coś w rodzaju(od stanu)->(do stanu).
Na szczęście istnieje bardzo wygodna metoda określania bieżącego stanu widoku jako stanu (from).
[UIView setAnimationBeginsFromCurrentState:YES];
Jeśli dodasz tę linię zaraz po beginAnimations: context: Twój kod działa idealnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 09:39:14
- (CGSize)keyboardSize:(NSNotification *)aNotification {
NSDictionary *info = [aNotification userInfo];
NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGSize keyboardSize;
if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) {
_screenOrientation = orientation;
if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize = [beginValue CGRectValue].size;
} else {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
}
} else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) {
// We didn't rotate
if (_screenOrientation == orientation) {
if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize = [beginValue CGRectValue].size;
} else {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
}
// We rotated
} else if (UIDeviceOrientationIsPortrait(orientation)) {
keyboardSize.height = [beginValue CGRectValue].size.width;
keyboardSize.width = [beginValue CGRectValue].size.height;
} else {
keyboardSize = [beginValue CGRectValue].size;
}
}
return keyboardSize;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 10:32:02
Oto dobre szczegóły http://i-phone-dev.blogspot.com/2012/01/different-way-to-show-keyboard-and.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-18 11:47:22