Nach stundenlanger anstrengender Arbeit beim Versuch, diese aktuellen Lösungen zu verwenden (und völlig gescheitert), habe ich endlich die Dinge zum Laufen gebracht und sie aktualisiert, um die neuen Animationsblöcke zu verwenden. Meine Antwort basiert vollständig auf der obigen Antwort von Ortwin .
Aus irgendeinem Grund funktionierte der obige Code für mich einfach nicht. Mein Setup schien anderen ziemlich ähnlich zu sein, aber vielleicht, weil ich auf einem iPad oder 4.3 war ... keine Ahnung. Es war ein bisschen verrückt zu rechnen und meine Tischansicht vom Bildschirm zu schießen.
Siehe Endergebnis meiner Lösung: http://screencast.com/t/hjBCuRrPC (Bitte ignorieren Sie das Foto .:-P)
Also ging ich zum Kern dessen über, was Ortwin tat, änderte jedoch die Art und Weise, wie Mathematik berechnet wurde, um den Ursprung und die Größe meiner Tabellenansicht mit der Höhe der Tastatur zu addieren. Wenn ich die Höhe des Fensters von diesem Ergebnis subtrahiere, wird mir angezeigt, wie viel Schnittpunkt ich habe. Wenn es größer als 0 ist (auch bekannt als Überlappung), führe ich die Animation der Rahmenhöhe durch.
Darüber hinaus gab es einige Probleme beim erneuten Zeichnen, die behoben wurden, indem 1) auf das Scrollen zur Zelle gewartet wurde, bis die Animation abgeschlossen war, und 2) die Option UIViewAnimationOptionBeginFromCurrentState beim Ausblenden der Tastatur verwendet wurde.
Ein paar Dinge zu beachten.
- _topmostRowBeforeKeyboardWasShown & _originalFrame sind Instanzvariablen, die im Header deklariert sind.
- self.guestEntryTableView ist meine tableView (ich bin in einer externen Datei)
- IASKCGRectSwap ist Ortwins Methode zum Umdrehen der Koordinaten eines Frames
- Ich aktualisiere die Höhe der Tabellenansicht nur, wenn mindestens 50 Pixel davon angezeigt werden
- Da ich nicht in einem UIViewController bin, habe ich keine self.view, also kehre ich einfach die tableView in ihren ursprünglichen Frame zurück
Auch hier wäre ich dieser Antwort nicht nahe gekommen, wenn Ortwin nicht den Kern davon geliefert hätte. Hier ist der Code:
- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
self.activeTextField = textField;
if ([self.guestEntryTableView indexPathsForVisibleRows].count) {
_topmostRowBeforeKeyboardWasShown = (NSIndexPath*)[[self.guestEntryTableView indexPathsForVisibleRows] objectAtIndex:0];
} else {
// this should never happen
_topmostRowBeforeKeyboardWasShown = [NSIndexPath indexPathForRow:0 inSection:0];
[textField resignFirstResponder];
}
}
- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
self.activeTextField = nil;
}
- (void)keyboardWillShow:(NSNotification*)notification {
NSDictionary* userInfo = [notification userInfo];
NSValue* keyboardFrameValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Reduce the tableView height by the part of the keyboard that actually covers the tableView
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation ) {
windowRect = IASKCGRectSwap(windowRect);
viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
keyboardFrame = IASKCGRectSwap(keyboardFrame);
}
// fix the coordinates of our rect to have a top left origin 0,0
viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);
CGRect frame = self.guestEntryTableView.frame;
_originalFrame = self.guestEntryTableView.frame;
int remainder = (viewRectAbsolute.origin.y + viewRectAbsolute.size.height + keyboardFrame.size.height) - windowRect.size.height;
if (remainder > 0 && !(remainder > frame.size.height + 50)) {
frame.size.height = frame.size.height - remainder;
float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration: duration
animations:^{
self.guestEntryTableView.frame = frame;
}
completion:^(BOOL finished){
UITableViewCell *textFieldCell = (UITableViewCell*) [[self.activeTextField superview] superview];
NSIndexPath *textFieldIndexPath = [self.guestEntryTableView indexPathForCell:textFieldCell];
[self.guestEntryTableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}];
}
}
- (void)keyboardWillHide:(NSNotification*)notification {
NSDictionary* userInfo = [notification userInfo];
float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration: duration
delay: 0.0
options: (UIViewAnimationOptionBeginFromCurrentState)
animations:^{
self.guestEntryTableView.frame = _originalFrame;
}
completion:^(BOOL finished){
[self.guestEntryTableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}];
}
#pragma mark CGRect Utility function
CGRect IASKCGRectSwap(CGRect rect) {
CGRect newRect;
newRect.origin.x = rect.origin.y;
newRect.origin.y = rect.origin.x;
newRect.size.width = rect.size.height;
newRect.size.height = rect.size.width;
return newRect;
}
CGRect FixOriginRotation(CGRect rect, UIInterfaceOrientation orientation, int parentWidth, int parentHeight) {
CGRect newRect;
switch(orientation)
{
case UIInterfaceOrientationLandscapeLeft:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), rect.origin.y, rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationLandscapeRight:
newRect = CGRectMake(rect.origin.x, parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationPortrait:
newRect = rect;
break;
case UIInterfaceOrientationPortraitUpsideDown:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
}
return newRect;
}