keyboard is hiding the text field in IOS [duplicate] - ios

This question already has answers here:
How can I make a UITextField move up when the keyboard is present - on starting to edit?
(98 answers)
Closed 9 years ago.
I have created a form in IOS using scrollview with some text fields. the view looks like this,
When I begin to edit either state or below fields, the keyboard hides that field. like this,
what should i do to see the below fields (i.e., state and below)??

You can try this code
Add following code at top of your viewcontroller.m file
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
CGFloat animatedDistance;
Inside textFieldShouldBeginEditing
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField
{
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
return YES;
}
Inside textFieldShouldEndEditing
- (BOOL) textFieldShouldEndEditing:(UITextField*)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}

You should definitely search for this in stack-overflow itself, before posting a question. Anyways, you can find the answer here.
Conform to protocol UITextFieldDelegate
Have a BOOL variable moved to signal, whether your view is moved or not.
Then implement the delegate methods.
-(void)textFieldDidBeginEditing:(UITextField *)textField {
if(!moved) {
[self animateViewToPosition:self.view directionUP:YES];
moved = YES;
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if(moved) {
[self animateViewToPosition:self.view directionUP:NO];
}
moved = NO;
return YES;
}
-(void)animateViewToPosition:(UIView *)viewToMove directionUP:(BOOL)up {
const int movementDistance = -60; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: #"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
viewToMove.frame = CGRectOffset(viewToMove.frame, 0, movement);
[UIView commitAnimations];
}

You need to use TPAvoidingKeyBoard Library into your app your problem is solved..
https://github.com/michaeltyson/TPKeyboardAvoiding
See this link. Download this project and add it into your project.
Then first you have to add scrollview to your view and then all your textfield into that scrollview add that TPAvoidingScrollView To Custom Class.

Your code is good. but you have to change UIScrollView y position instead of height. I have change your code and update. please update this
step 1: In the ViewDidLoad method of your class set up to listen for messages about the keyboard:
// Listen for keyboard appearances and disappearances
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
step 2: up/down your scrollview by implementing selector methods in same class
- (void)keyboardDidShow: (NSNotification *) notif{
//Keyboard becomes visible
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y - 220,
scrollView.frame.size.width,
scrollView.frame.size.height); //move up
}
- (void)keyboardDidHide: (NSNotification *) notif{
//keyboard will hide
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y + 220,
scrollView.frame.size.width,
scrollView.frame.size.height); //move down
}

Try this code
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField==tfLocation)
{
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y-50, self.view.frame.size.width, self.view.frame.size.height)];
}
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self.view setFrame:CGRectMake(self.view.frame.origin.x, 0, self.view.frame.size.width, self.view.frame.size.height)];
}

Related

Moving textfield up with keyboard

I have this layout shown in the picture below:
I have this code to move the Email Address textfield up when the keyboard pops up:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
textfield1.frame = CGRectMake(textfield1.frame.origin.x, (textfield1.frame.origin.y - 100.0), textfield1.frame.size.width, textfield1.frame.size.height);
[UIView commitAnimations];
}
The only problem is when I move the textfield up like this it covers the Email Login / Sign Up Label right above it. Is there any way I can move the Email Address textfield up without covering that label? Or do I have to move every single view (such as the label) that is above that Email Address textfield up as well?
Consider observing the system notifications:
UIKeyboardWillShowNotification
UIKeyboardDidShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification
And check the documentation
You should move the view that wraps all the UITextFields (if no such view, just create a "form view" containing those fields). The userInfo property of the notification object contains the size of the keyboard. You can use that information and position the form view with a distance from the keyboard frame.
First You have to add keyboard notification observer "UIKeyboardWillShowNotification" in your viewDidLoad or any other initialiser method as:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
Then define the method "keyboardWillShow:" in your view controller class as:
- (void)keyboardWillShow:(NSNotification*)notification
{
NSDictionary *info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGFloat _currentKeyboardHeight = kbSize.height;
}
Now you will get Keyboard height value. Based on this value You can adjust your textfield's 'y' position.
Add scrollview as subview to existing View and then place all controls on this subview.
Use below code for smooth keyboard push while text editing.
//Declare in implementation file
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
//static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
#pragma - UITextField Delegates
- (void)textFieldDidBeginEditing:(UITextField *)textField {
//Perform Animation during Keyboard show and Hide
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0) {
heightFraction = 0.0;
}
else if (heightFraction > 1.0) {
heightFraction = 1.0;
}
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
Refer this link.
As an alternative to the above answers, have you considered using a UIAlertController instead? These auto-format to be where you'd want them to be so that the user can always type without stuff being ugly (well, not always, but most of the time). You can read more about implementation here, but the general gist would be something like this:
UIAlertController* passAlert = [UIAlertController alertControllerWithTitle:#"Email Login/Sign Up" message:#"" preferredStyle:UIAlertControllerStyleAlert];
[passAlert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
textField.placeholder = NSLocalizedString(#"username", #"username");
}];
[passAlert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
textField.placeholder = NSLocalizedString(#"password", #"password");
}];
UIAlertAction* doneAction = [UIAlertAction actionWithTitle:#"Done" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) {
// do whatever you need to do to process the login and password
}];
[passAlert addAction:doneAction];
In the interest of transparency, my deep wisdom and arcane knowledge of textfields in alerts comes from here.
Very likely the other answers given are more useful for your case - you have a nice looking UI, a dope kind of Google Cards type thing, and I bet you don't want to give that sick look up. But if you'd like a cool alternative, here's one that should work more consistently than most peoples' ad-hoc solutions :).

Setting inputAccessoryView for a UitextField

I just want to make the UITextField to go up when keyboard was presented. I achieved it by setting the frame of UITextField after keyboard was presented. It is working for ordinary cases. But, if user enabled prediction in default keyboard then predictive text area gets placed above the UITextField. In that case I want the text field to move up. I tried setting inputAccessoryView of textfield. But app crashed with no report .So how can I set inputAccessoryView of textfield to achieve my requirement.
textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, bottomToolbarView.frame.size.width, bottomToolbarView.frame.size.height)];
textField.delegate = self;
textField.textAlignment = NSTextAlignmentCenter;
textField.inputAccessoryView = bottomToolbarView;
[textField setReturnKeyType:UIReturnKeyGo];
[textField setPlaceholder:#"Enter Employee Id"];
[textField setBackgroundColor:[UIColor colorWithRed:1.000 green:0.720 blue:0.611 alpha:1.000]];
[bottomToolbarView addSubview:textField];
try this code in textfield Did Begin Editing delegate method
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size. height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
& on didEndEditing delegate method
-(void)textFieldDidEndEditing:(UITextField *)textField1
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}

Textfields is hiding by the Keypad [duplicate]

This question already has answers here:
How can I make a UITextField move up when the keyboard is present - on starting to edit?
(98 answers)
Closed 8 years ago.
I have made an app with a Registration form. When the Textfield in this form is selected it gets hidden by the soft keyboard. If i leave it as it is user can't see what he is entering while typing.
Try this may be helpfull..
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[self animateTextField:textField up:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
[self animateTextField:textField up:NO];}
-(void)animateTextField:(UITextField*)textField up:(BOOL)up
{
int movementDistance = -100; // tweak as needed
float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: #"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
this is the old method ,but working fine for each time
in your .h file
#interface signupViewController : UIViewController
{
CGFloat animatedDistance;
}
.m file
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}

How do you move a UITextField in response to the keyboard appearing and disappearing in iOS7?

How do you move a UITextField on the screen so that it is not covered by the keyboard in iOS7, and then return it to its original spot inside the UIView once the keyboard is dismissed?
in your Viewcontroller.h
#interface ViewController : UIViewController<UITextFieldDelegate>
{
CGFloat animatedDistance;
}
in ViewController.M
//paste the below 4 line in anywhere on the class (outside the method)
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
in delegate methods are
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
You have to catch the notification for UIKeyboardWillShowNotification and edit your frames to move the UITextField to the right place (for example by using [UIView animateWithDuration:(NSTimeInterval) animations:^(void)animations]).
Here is a sample...
In init, add an observer on UIKeyboardWillShowNotification :
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil];
Then add the - keyboardWillShow method to update your view (supposing _textfield is the name of your UITextField) :
- (void)keyboardWillShow {
NSLog(#"Show Keyboard");
[UIView animateWithDuration:.2 animations:^{
[_textField setFrame:_textField.frame];
[_textField setFrame:CGRectMake(_textfield.frame.origin.x, _textfield.frame.origin.y - 240, _textfield.frame.size.width, _textfield.frame.size.height)];
}];
}
You can use the UIKeyboardWillShowNotification notification to perform the inverse action.
I recommend to use a UIScrollView to move your content up, when the keyboard is shown.
Also Apple discourages us from using self defined constants for the keyboardsize: Other Languages may have different sizes. The correct size is embedded in the userInfo of the Notification:
Get the notifications for keyboard changes :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeShown:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
Remember to remove the observer like:
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
These methods handle the keyboard changes:
- (void)keyboardWillBeShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGRect kbRect = [self.view.window convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.scrollView];
CGSize kbSize = kbRect.size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
NSTimeInterval duration = [info[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}];
}
Of course you could also manipulate the frame of the UITextView with these methods.

Scrolling a table view with text fields when "Next" return button in keyboard

I have a grouped table view with custom cells, and these cells have a UITextField. I've set the returnKeyType of the text fields to be UIReturnKeyNext (except for the last row), and I've implemented their textFieldShouldReturn: method this way:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
id firstResponderCell = textField.superview.superview ;
NSInteger firstResponderRow = [self.tableView indexPathForCell:firstResponderCell].row ;
NSIndexPath* nextCellIndexPath = [NSIndexPath indexPathForRow:firstResponderRow+1 inSection:0] ;
CustomCell* nextCell = (CustomCell*)[self.tableView cellForRowAtIndexPath:nextCellIndexPath] ;
if (nextCell) {
[nextCell.cellTextField becomeFirstResponder] ;
}
else
[textField resignFirstResponder] ;
return YES ;
}
But I'm not able to scroll the table view content in order to make the current active text field visible above the keyboard. I successfully managed this when I did not implement the "Next" button functionality in keyboard and keyboard was just hidden when "Enter" button was tapped, and then the keyboard was again shown when another text field was tapped, since I'm listening for UIKeyboardDidShowNotification and UIKeyboardDidHideNotification. But now that I want a "Next" button in keyboard and keyboard is not being hidden when tapping the button, I donĀ“t know how to scroll to the active text field properly.
Thanks in advance
This is the most easiest and efficient way to achieve this:
Add the following constants:
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;
Add this to your view controller:
CGFloat animatedDistance;
And add these methods to your code:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
P.S: This one is from here.
This isn't a safe way of getting the cell:
id firstResponderCell = textField.superview.superview ;
I.e. It might work now but it might not work in the (near) future.
Once you know the index path you should check that it actually exists. Then you can use scrollToRowAtIndexPath:atScrollPosition:animated: to scroll the row (and make it the top row). Alternatively you can get the frame of the row and then set the contentOffset of the table view.

Resources