Le code suivant résout un problème dans de Jay réponse, qui suppose qu' UIKeyboardWillShowNotification
ne se déclenche pas à nouveau lorsque le clavier est déjà présent.
Lors de la saisie avec le Chinois/Japonais clavier, iOS déclenche un extra - UIKeyboardWillShowNotification
avec le nouveau clavier de l'image même si le clavier est déjà présent, conduisant à la hauteur de l' self.textView
réduit une deuxième fois dans le code d'origine.
Cela réduit self.textView
à presque rien. Il devient alors impossible de les récupérer à partir de ce problème, car nous ne prévoyons un seul UIKeyboardWillHideNotification
la prochaine fois que le clavier est rejeté.
Au lieu de soustraire/ajout de la hauteur d' self.textView
selon que le clavier est affiché/caché comme dans le code d'origine, le code suivant calcule le maximum de hauteur pour self.textView
après la soustraction de la hauteur du clavier à l'écran.
Cela suppose qu' self.textView
est supposé remplir la totalité de l'affichage de la vue-contrôleur, et il n'y a pas d'autres sous-vue qui doit être visible.
- (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];
}
}
Aussi, n'oubliez pas de vous inscrire le clavier notifications dans le 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];
}
A propos du fractionnement du redimensionnement de code en deux parties
La raison pour laquelle le textView redimensionnement code est divisé en deux parties (resizeTextViewWithKeyboardNotification:
et resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
) est de fixer un autre problème lorsque le clavier persiste à travers une poussée à partir d'un point de vue contrôleur à l'autre (voir Comment puis-je détecter le clavier iOS quand elle reste entre les contrôleurs?).
Comme le clavier est déjà présent avant que le contrôleur est poussé, il n'y a pas de clavier supplémentaire de notifications générées par iOS, et donc aucun moyen de redimensionner l' textView
basés sur ceux du clavier notifications.
Le code ci-dessus (ainsi que le code d'origine) qui se redimensionne self.textView
seulement de travail lorsque le clavier est affiché après le point de vue a été chargé.
Ma solution est de créer un singleton qui stocke la dernière clavier coordonnées, et sur l' - viewDidAppear:
de la viewController, composez le:
- (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
est mon singleton ici. Idéalement, nous devrions appeler cette en - viewWillAppear:
, mais dans mon expérience (au moins sur iOS 6), l' convertRect:fromView:
méthode que nous avons besoin d'utiliser en resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
ne pas convertir correctement le clavier de l'image à l'affichage des coordonnées avant le point de vue est entièrement visible.