Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you can use <code>UITableViewController</code>, you get the functionality for free. Sometimes, however, this is not an option, specifically if you need multiple views not just the <code>UITableView</code>.</p> <p>Some of the solutions presented here don't work on iOS ≥4, some don't work on iPad or in landscape mode, some don't work for Bluetooth keyboards (where we don't want any scrolling), some don't work when switching between multiple text fields. So if you choose any solution, make sure to test these cases. This is the solution we <strike>use</strike> <strong>used</strong> in <a href="http://www.inappsettingskit.com/" rel="noreferrer">InAppSettingsKit</a>:</p> <pre><code>- (void)_keyboardWillShow:(NSNotification*)notification { if (self.navigationController.topViewController == self) { NSDictionary* userInfo = [notification userInfo]; // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0 NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"]; if (!keyboardFrameValue) { keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"]; } // Reduce the tableView height by the part of the keyboard that actually covers the tableView CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds; if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) { windowRect = IASKCGRectSwap(windowRect); } CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]]; if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) { viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute); } CGRect frame = _tableView.frame; frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute); [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = frame; [UIView commitAnimations]; UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview; NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell]; // iOS 3 sends hide and show notifications right after each other // when switching between textFields, so cancel -scrollToOldPosition requests [NSObject cancelPreviousPerformRequestsWithTarget:self]; [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; } } - (void) scrollToOldPosition { [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)_keyboardWillHide:(NSNotification*)notification { if (self.navigationController.topViewController == self) { NSDictionary* userInfo = [notification userInfo]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = self.view.bounds; [UIView commitAnimations]; [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1]; } } </code></pre> <p>Here's the <a href="https://github.com/futuretap/InAppSettingsKit/blob/9f32e0c6fc6aa66c10595aaf2ad99d040270ce14/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m" rel="noreferrer">full code of the class</a> in InAppSettingsKit. To test it, use the "Complete List" child pane where you can test the scenarios mentioned above.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload