Keypad hides View (AutoLayout + StoryBoard) - ios

Apologies for this basic question, I am new to iOS development. I have a UITextField in a View with AutoLayout that I would like to use to key in messages for a chat system. However when the keypad is displayed it hides the View containing the UITextField (the entire View is behind the keypad).
What should be done to move the View along with the keypad when the keypad transitions from the bottom? The UIView should be back in its original position (at the bottom of the screen) when the keypad is dismissed. My entire UI has been designed with AutoLayout in Storyboard.
Edit:
I looked up How do I scroll the UIScrollView when the keyboard appears? for a solution however there doesn't seem to be any indication AutoLayout has been used along constraints in this answer. How can the same be achieved using AutoLayout in Storyboard. Again, apologies for any lack of understanding as I am very new to iOS development.

Add a UIScrollView to your view controller and keep your UITextField over scrollview.
add UITextFieldDelegate
yourTextField.delegate = self;
you can set content offset of scrollview when touch on UITextField and reposition it to (0, 0) when keyboard resign.
-(void)viewWillAppear:(BOOL)animated
{
yourScrollView.contentSize = CGSizeMake(320, 500);
[super viewWillAppear:YES];
}
-(void)textFieldDidBeginEditing:(FMTextField *)textField
{
[yourScrollView setContentOffset:CGPointMake(0,textField.center.y-140) animated:YES];//you can set your y cordinate as your req also
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
[yourScrollView setContentOffset:CGPointMake(0,0) animated:YES];
return YES;
}

This is what I did recently, may be it helps.
All my fields are inside a wrapper view with a top constraint. Since for me moving the wrapper view a few pixels up and down was enough I use this approach.
Here is an example with a scroll view.
I use a IBOutlet to reference this constraint
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//register for keyboard notifications
_keyboardIsShowing = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
Then on the notification methods
#pragma mark - Keyboard notifications methods
- (void)keyboardWillShow:(NSNotification *) notification{
if (!_keyboardIsShowing) {
_keyboardIsShowing = YES;
[UIView animateWithDuration:0.4 animations:^{
//here update the top constraint to some new value
_topConstraint.constant = _topConstraint.constant - 30;
[self.view layoutIfNeeded];
}];
}
}
- (void)keyboardWillHide:(NSNotification *) notification{
if (_keyboardIsShowing) {
[UIView animateWithDuration:0.4 animations:^{
_topConstraint.constant = _topConstraint.constant + 30;
[self.view layoutIfNeeded];
}];
_keyboardIsShowing = NO;
}
}
There are tons of this kind of answers here on SO.
Good luck.

Related

Adjusting Contraints for iOS Keyboard Height inside UIWebView

I have a simple browser view controller used as part of a storyboard. It starts out looking great. My UIToolBar is anchored to the bottom of the UIView via a Vertical Space constraint of 0.
When you hit something on the webpage that brings up the keyboard. The UIToolBar is hidden. So I added a listener for the keyboard visibility change and adjusted the constraint based on the height of the keyboard. This seems to work well.
However, if the user then hits the minimize button on the keyboard, the keyboard doesn't totally go away. The top bar of arrow keys to allow for tabbing between input fields (I don't know what to call it) will remain visible. So I cannot set my constraint back to 0, I have to set it again based on the height of the visible keyboard (which I would think would include that top bar).
However when my UIKeyboardDidHideNotification fires, the keyboard height is still the same so I end up like this.
My logic for moving the constraint is based on acquiring the keyboard height this way:
// get height of visible keyboard
NSDictionary* keyboardInfo = [aNotification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
_toolbarBottomVerticalSpaceConstraint.constant = -1 * keyboardFrameBeginRect.size.height;
Is UIKeyboardFrameBeginUserInfoKey not the based value to use in the case of the keyboard being hidden?
The entire source for this view controller is actually really simple at the moment so I'll include all of it in case someone asks for it later.
#import "LEPopupBrowserViewController.h"
#interface LEPopupBrowserViewController ()
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *toolbarBottomVerticalSpaceConstraint;
#end
#implementation LEPopupBrowserViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
if (_url != nil) {
NSMutableURLRequest * request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:_url]];
[_webView loadRequest:request];
}
}
- (void) viewDidUnload {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWillShow:(NSNotification*)aNotification
{
// get height of visible keyboard
NSDictionary* keyboardInfo = [aNotification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
_toolbarBottomVerticalSpaceConstraint.constant = -1 * keyboardFrameBeginRect.size.height;
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardDidHide:(NSNotification*)aNotification
{
// get height of visible keyboard
NSDictionary* keyboardInfo = [aNotification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
_toolbarBottomVerticalSpaceConstraint.constant = -1 * keyboardFrameBeginRect.size.height;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)doneButtonPressed:(id)sender {
// close keyboard if present
[self.view endEditing:YES];
// dismiss ourselves
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Update
I found through some additional research it appears this additional view is called the accessoryView. I see lots of posts of people trying to remove it but haven't found anything where you could find it's height easily. The bothersome part about removing it to me is it seems Apple may reject your app.

UIToolBar reverts after changing a label

I've got a UIToolBar with a UITextField in it, along with a Label. I'm trying to get the label to update when the user types so they know how many characters they've typed.
Currently the UIToolBar returns to its original position when I try and update the label counter. Here is a gif showing the issue I'm having.
All I'm doing is the following:
-(IBAction)CharCount:(id)sender{
NSString *substring = textField.text;
NSString *limitHit;
limitHit = substring;
int maxChar = 160;
if (limitHit.length > 0) {
TextCounter.hidden = NO;
TextCounter.text = [NSString stringWithFormat:#"%d/160", limitHit.length];
}
}
How would I go about updating the label without reversing the animation to move the toolbar along with the keyboard?
======================== Edit ========================
Not using auto-layout means my view on an iPhone 4S is wrong. Their's an example below. The menu at the bottom hangs off. How do I set it so that doesn't happen?
Don't turn off auto layout, just change constraints instead of frames. Changing frames with auto layout does not work because of layoutSubviews method. This method is called by system in many cases. You need:
Add a bottom constraint to your toolbar:
Subscribe for keyboard notifications.
Change bottom constraint of your toolbar when keyboard will show or hide.
Code sample:
- (void)dealloc {
[self unsubscribeForKeyboardNotifications];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self subscribeForKeyboardNotifications];
}
#pragma mark - Keyboard notifications
- (void)subscribeForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillAppear:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillDisappear:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)unsubscribeForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillAppear:(NSNotification *)notification {
CGFloat keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
[self changeToolbarBottomConstraintWithConstant:keyboardHeight];
}
- (void)keyboardWillDisappear:(NSNotification *)notification {
[self changeToolbarBottomConstraintWithConstant:0];
}
- (void)changeToolbarBottomConstraintWithConstant:(CGFloat)constant {
[self.toolBar.superview.constraints enumerateObjectsUsingBlock:
^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.secondItem == self.toolBar && constraint.secondAttribute == NSLayoutAttributeBottom)
constraint.constant = constant;
}];
[UIView animateWithDuration:0.5
animations:^{
[self.view layoutIfNeeded];
}];
}
Result:
Every part of this looks like it could be simplified and solved by setting the UIToolbar as the UITextview's inputAccessoryView. This will attach the toolbar to the keyboard as it animates up and down. If you want it to remain at the bottom of the view in the View Controller you can overwrite the inputAccessoryView of the View Controller and then add this method to your View Controller's implementation file:
- (BOOL)canBecomeFirstResponder {
return YES;
}
Here is a handy intro to using an inputAccessoryView on a view controller.
no need to remove autolayout just add two constraint trailing space to toolbarview and fix width constraint
hope this will help you i have similar problem and i resolve with this way so.
You can do it without auto layout also by setting frames. Take textField and label in a view called InputView and add it in self.view and your textField as tfInput.
now set delegate for textfield in your view controller.
Then, Just change the Y position of view according to requirement.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField== tfInput)
{
InputView.frame = CGRectMake(InputView.frame.origin.x,self.view.frame.size.height - 216 - InputView.frame.size.height,InputView.frame.size.width,InputView.frame.size.height);
}
return YES;
}
and
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField== tfInput)
{
InputView.frame = CGRectMake(InputView.frame.origin.x,self.view.frame.size.height - 49 InputView.frame.size.height,InputView.frame.size.width,InputView.frame.size.height);
}
return YES;
}
here I set 49 as a toolbar size, it may be custom size by you.
And also you can do some animation while frame set.
this is a one option by frame set.
second option is put it in a scrollview and in same textfield delegate method textFieldShouldBeginEditing you have to just set content offset to your needed place and make it 0 in textFieldShouldReturn.

iOS- Change of UITextField height and movement of Buttons based on keyboard display

I am having an view in iOS where there is an UITextfield and 3 UIbuttons below the UITextField. Please see below for the pic. When this view is launched, the default state is STATE1.(Please see image). The keyboard is visible by default. Now when I dispose the keyboard, I wish to have the edittext resized and occupy the whole screen as shown in STATE2.
I am not sure how to accomplish this. I have the height of the UITextfield hardcoded to some dp based on the target device. I believe this has to be changed and it has to dynamically occupy the screen based on the screen size.
Can anyone help me accomplish this. Please consider the button is like a tail to the edit text. This clings to the edit text no matter the keyboard is visible or not. Thanks
You can use TPKeyboardAvoiding library and achieve this what you want.
First you have to use UITextView instead of UITextField
The register your class for
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Implement this methods
- (void)keyboardWillHide:(NSNotification *)notification {
[self resizeViewWithOptions:[notification userInfo]];
}
- (void)keyboardWillShow:(NSNotification *)notification {
[self resizeViewWithOptions:[notification userInfo]];
}
- (void)resizeViewWithOptions:(NSDictionary *)options {
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[options objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[options objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[options objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:animationCurve];
[UIView setAnimationDuration:animationDuration];
CGRect viewFrame = self.view.frame;
CGRect keyboardFrameEndRelative = [self.view convertRect:keyboardEndFrame fromView:nil];
NSLog(#"keyboardFrameEndRelative: %#", NSStringFromCGRect(keyboardFrameEndRelative));
// Now set Frame for UITextView and UIbuttons frame here
}
Try like this even simpler first add those controls what you want which looks like in state 1
in viewDidAppear add the following function
-(void)viewDidAppear:(BOOL)animated
{
[self.Textfield1 becomeFirstResponder];
}
so it will load keyboard when the view loads
then add this lines to .m to close the keyboard press return it will hide keyboard
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
//Write your coding for resizing size dynamically to show look like state 2
//Here check version of device to set as per height
textfield.frame=CGRectMake(0,0,320,400);
button1.frame=CGRectMake(0,400,320,400);
[textField resignFirstResponder];
return YES;
}
don forget to add delegate for textfield

Keyboard does not disappear after viewDidDisappear on iOS 7

In our app, there's a situation where the user enters something in a textbox and then presses the back button to go back to the master screen.
If we run that on iOS 7, the keyboard does not disappear, it just stays there. The user can still navigate through the app, but all text fields are disabled, meaning you can't enter text anywhere. The only option the user has is killing the app and starting fresh.
We tried to add resignFirstResponder messages, but that didn't help anything.
There's much code involved, and we're actively working on the issue. Meantime, has anyone experienced that problem too, and maybe found a way to make it go away?
I had the same issue like you when I compiled the app for iOS 7 and I did the following changes:
Make sure you add [textfield resignFirstResponder] before dismissing the viewController for example:
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
[self performSegueWithIdentifier:#"forgotPassword" sender:self];
Just to be sure the keyboard disappears add [textfield resignFirstResponder] in viewWillDisappear for example :
- (void) viewWillDisappear:(BOOL)animated
{
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
}
If your viewController is presented using UIModalPresentationFormSheet add this to your viewController just to make sure the textfields will respond resignFirstResponder:
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
In your case, override the back button action or just use viewWillDisappear to check when the user pressed the back button and then call resignFirstResponder before [super viewWillDisappear] something like this:
-(void) viewWillDisappear:(BOOL)animated
{
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
[super viewWillDisappear:animated];
}
Try [self.view resignFirstResponder], instead of [textfield resignFirstResponder] on viewWillDisappear.
[textfield resignFirstResponder] should do the job, but to make sure and for not to loop through all your textFields you can use:
[self.view endEditing:YES];
From the doc:
use to make the view or any subview that is the first responder resign
(optionally force).
in general I find this useful
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
you can add this in viewWillDisappear: or viewDidDisappear:
this will hide the keyboard without a reference to the currently focused text field
I had the same problem only with MoreViewController in UITabBarController (iOS 8.3). Maybe this solution not very 'nice' and little complicated, but seems like it works, hope it will help you too.
#interface ViewController ()
#property (nonatomic) BOOL needToHideKeyboard;
#property (nonatomic, strong) IBOutlet UITextField *txtField;
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.needToHideKeyboard = NO;
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self hideKeayboard];
}
- (void)hideKeayboard
{
if (self.needToHideKeyboard) {
[self.txtField resignFirstResponder];
}
}
- (void)keyboardWasShown:(NSNotification *)notification
{
self.needToHideKeyboard = YES;
NSDictionary *info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// Shift scroll view content insets on the keyboard height
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom = keyboardSize.height;
self.scrollView.contentInset = contentInsets;
}
- (void)keyboardWillBeHidden:(NSNotification *)notification
{
self.needToHideKeyboard = NO;
// Reset keyboard content insets
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom = [self.bottomLayoutGuide length];
self.scrollView.contentInset = contentInsets;
}
#end
If your view controller implements textFieldDidEndEditing, make sure you don't set another view to be the first responder if the view is disappearing. textFieldDidEndEditing will get invoked when you call resignFirstResponder, or [self.view endEditing:YES].
[self.view endEditing:YES];
stopped working on my device iOS9.x
We can also do this in the viewWillDisappear method
for (UIView *subview in self.view.subviews) {
if ([subview canPerformAction:#selector(endEditing:) withSender:nil]) {
[subview endEditing:YES];
}
if ([subview canResignFirstResponder]) {
[subview resignFirstResponder];
}
}
This will loop through the responders and resign the responder status.

is this a valid workaround to keyboard obscuring content

I have a Tableview where the user can enter values into a textField as one of the custom cells
Apple have some documentation about how to adjust view content by repositioning the view clear of the keyboard's vertical dimension ( Here ) but it relies upon one placing that view into a UIScrollView. I cant do this with a tableview.
I could redesign the app so that the entry gets done in a separate detail view using the usual navigation controller, but i'd rather the user not have to perform an extra touch ( and be ferried off into yet another screen ) if possible. I like the idea of doing the deed "right where we are"
so my workaround to have a few extra tableview cells at the bottom containing a %20 or so, normal usage shouldn't register the oddity, as they are only focussed on what is visible.
I'd have to store the spaces in my datasource array and then sort descending, but that's OK
the question is, is this good practice? and even more possibly, could it be against Apple's HIG sufficient for refusal?
UITableView is a subclass of UIScrollView, so should be able to adjust the content and scroll view insets just like in the example you linked.
The way I've solved this issue is to subclass UITableView. Here's what I've done:
// AOTableView.h file
typedef enum
{
AOKeyboardStateUnknown = 0,
AOKeyboardStateShowing,
AOKeyboardStateHidden
} AOKeyboardState;
#import <UIKit/UIKit.h>
#import "AOKeyboardState.h"
#interface AOTableView : UITableView
#property (nonatomic) BOOL observeKeyboardNotifications;
#property (nonatomic) AOKeyboardState keyboardState;
#end
// AOTableView.m file
#import "AOTableView.h"
#interface AOTableView(Private)
#property (nonatomic) CGRect frame0;
- (void)setup;
- (void)keyboardWillShow:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification *)notification;
#end
#implementation AOTableView
#pragma mark - Object lifecycle
- (void)awakeFromNib
{
[self setup];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setup];
}
return self;
}
- (void)setup
{
self.contentSize = self.frame.size;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_keyboardState = AOKeyboardStateUnknown;
_frame0 = self.frame;
_observeKeyboardNotifications = NO;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Custom setters
- (void)setObserveKeyboardNotifications:(BOOL)observeKeyboardNotifications
{
if (_observeKeyboardNotifications == observeKeyboardNotifications)
return;
_observeKeyboardNotifications = observeKeyboardNotifications;
if (_observeKeyboardNotifications)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
else
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
}
#pragma mark - UIKeyboard Notifications
- (void)keyboardWillShow:(NSNotification *)notification
{
if (self.keyboardState == AOKeyboardStateShowing)
return;
self.frame0 = self.frame;
self.keyboardState = AOKeyboardStateShowing;
NSDictionary* info = [notification userInfo];
CGRect keyboardFrame = CGRectZero;
[[info objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
CGRect frame = self.frame0;
frame.size.height = CGRectGetMinY(keyboardFrame) - CGRectGetMinY(frame);
self.frame = frame;
[self scrollToRowAtIndexPath:self.indexPathForSelectedRow atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
[self deselectRowAtIndexPath:self.indexPathForSelectedRow animated:NO];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
if (self.keyboardState == AOKeyboardStateHidden)
return;
self.keyboardState = AOKeyboardStateHidden;
self.frame = self.frame0;
}
#end
After creation (or loading the view from an IBOutlet), you call this method to tell the class to start listening for keyboard notifications:
[tableViewInstance setObserveKeyboardNotifications:YES];
Whenever a user clicks on a cell, it becomes the self.indexPathForSelectedRow cell... so its scrolled to by the AOTableView instance automatically.
For this to work, though, I've had to turn off userInteraction on the UITextField within the cell (otherwise, the device can get confused about if the user is clicking on the cell or on the text field). Instead, when a user selects a cell that has a text field, I tell the text field to the become first responder, like this:
[cell.textField becomeFirstResponder];
I hope this helps.
You don't need the extra cells or anything fancy.
Since your text fields are inside the table view cells, you can use the following:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
UITableViewCell *cell = (UITableViewCell *)textField.superview.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
return YES;
}
This means that the keyboard will scroll appropriately each time a text field becomes first responder. This takes advantage of the table view being a scroll view subclass.
Note that this assumes:
Your (table) view controller is the text fields' delegate.
Your text field is a subview of the cell's content view, not the cell itself.
If the text field is a subview of the cell, the first line of the method above should reference only one superview (i.e., textField.superview).

Resources