i had created a navigation based small application. When I click to the table row, it display controller having UIScrollView and number of TextFields added in it, when i returned back to main controller, then again i navigate to that controller, it do not scroll and still contain previous values in textfield. I am not able to know where is the problem.
Here is my code:
rootcontroller.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch(indexPath.row)
{
case 1:
if(insertViewController == nil)
insertViewController = [[insertView alloc] initWithNibName:#"insertView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:insertViewController animated:YES];
break;
//[insertViewController release];
}
}
insertviewcontoller.m
#import "insertView.h"
#import "RootViewController.h"
#import "Foundation/Foundation.h"
#define kTabBarHeight 5.0
#define kKeyboardAnimationDuration 1.0
#implementation insertView
#synthesize scroll;
- (void)viewDidLoad {
[super viewDidLoad];
//for scrolling
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
CGSize scrollContentSize = CGSizeMake(320, 345);
self.scroll.contentSize = scrollContentSize;
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
NSValue* boundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
// resize the scrollview
CGRect viewFrame = self.scroll.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height += (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
// The kKeyboardAnimationDuration I am using is 0.3
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.scroll setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
- (void)keyboardWillShow:(NSNotification *)n
{
// This is an ivar I'm using to ensure that we do not do the frame size adjustment on the UIScrollView if the keyboard is already shown. This can happen if the user, after fixing editing a UITextField, scrolls the resized UIScrollView to another UITextField and attempts to edit the next UITextField. If we were to resize the UIScrollView again, it would be disastrous. NOTE: The keyboard notification will fire even when the keyboard is already shown.
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
NSValue* boundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scroll.frame;
// I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
// The kKeyboardAnimationDuration I am using is 0.3
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.scroll setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- (void)dealloc {
[super dealloc];
[scroll release];
[nmtf release];
[phtf release];
[addtf release];
}
update viewDidLoad method into viewWillAppear:(BOOL)animated in your insertviewcontoller.m page
Related
So, as often suggested for people who want the view to be pushed up when the keyboard appears, I use a UIScrollView. I copied and pasted the information from this page -- http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW7 -- to do that...
But what happens is, when I tap the text fields, the keyboard pops up, but the view actually scrolls DOWN, revealing black on top. After that, I can actually manually scroll the view up and reveal the hidden text fields...obviously, that's not what I'm trying to do!
Any ideas? I have the following in the viewDidLoad() method:- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}
I've tried this version of keyboardWasShown:
- (void) keyboardWasShown:(NSNotification *)aNotification
{
NSDictionary * info = [aNotification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0,keyboardSize.height, 0);
[[self introScroll] setContentInset:contentInsets];
[[self introScroll] setScrollIndicatorInsets:contentInsets];
CGRect ltdRect=[[self view] frame];
ltdRect.size.height=keyboardSize.height;
if (!CGRectContainsPoint(ltdRect,[self activeField].frame.origin))
{
CGPoint scrollPoint = CGPointMake(0,[self activeField].frame.origin.y-keyboardSize.height);
[[self introScroll] setContentOffset:scrollPoint animated:YES];
}
NSLog(#"Keyboard out!");
}
as well as this version of keyboardWasShown:
- (void)keyboardWasShown:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = [[[self activeField] superview ]frame];
bkgndRect.size.height += kbSize.height;
[[[self activeField] superview] setFrame:bkgndRect];
[[self introScroll] setContentOffset:CGPointMake(0.0, [self activeField].frame.origin.y-kbSize.height) animated:YES];
}
Both give me the exact same results.
What's going on?? I'm using Xcode 4.6.
I had a similar problem that my text fields did not scroll into view.
the apple code is not perfect, I had to modify it:
Try to solve that by adding the height of active field in line:
frame.origin.y + frame.size.height - keyboardSize.height
If that does not work, add 44 to scrollpoint.y (size of navigation bar)
Update for ios7:
I improved unwanted and wrong scrolling in ios7 for text fields, that are already in view
by
if (scrollPtY < 0) {
return;
}
Hi can someone help me create this feature, I would like to have a text box at the bottom of my app, and as soon as the user clicks on it, it should raise that text box to the middle of screen right above the keyboard. Similar to skype app, thanks!
Try This
#define kKeyboardAnimationDuration 0.3
#interface YourViewController:UIViewController
{
BOOL keyboardIsShown;
}
And then in your implementation
- (void)viewDidLoad
{
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
keyboardIsShown = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
#pragma mark - Keyboard Events
- (void)keyboardWillShow:(NSNotification *)n
{
if (keyboardIsShown)
{
return;
}
NSDictionary* userInfo = [n userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y-= (keyboardSize.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- (void)keyboardWillHide:(NSNotification *)n
{
NSDictionary* userInfo = [n userInfo];
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y+= (keyboardSize.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
I want to create a view, like the Facebook or Twitter app's share dialog, for example, where there is just a UITextView and a permanent keyboard. I can see how to start with the keyboard visible from this answer, but I'm not sure how to size the UITextView to fit exactly above the keyboard. If I don't, text can get hidden under the keyboard which is awkward.
You can subscribe to UIKeyboardWillShowNotification. The notification includes the frame of the keyboard, so you can size your view to fit the remaining space.
I found a helpful code sample in the Apple documentation for this: https://developer.apple.com/library/ios/#samplecode/KeyboardAccessory/Introduction/Intro.html
Here's the code I ended up with. I'm not worrying about the keyboard hiding, since in my view, the keyboard should never hide.
- (void)viewWillAppear:(BOOL)flag
{
[super viewWillAppear:flag];
// Listen for the keyboard to show up so we can get its height
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// Set focus on the text view to display the keyboard immediately
[self.textView becomeFirstResponder];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
/*
Reduce the size of the text view so that it's not obscured by the keyboard.
*/
NSDictionary *userInfo = [notification userInfo];
// Get the origin of the keyboard when it's displayed.
NSValue* keyboardFrame = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Get the top of the keyboard as the y coordinate of its origin in self's view's
// coordinate system. The bottom of the text view's frame should align with the
// top of the keyboard's final position.
CGRect keyboardRect = [keyboardFrame CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
// Set the text view's frame height as the distance from the top of the view bounds
// to the top of the keyboard
CGFloat keyboardTop = keyboardRect.origin.y;
CGRect newTextViewFrame = self.view.bounds;
newTextViewFrame.size.height = keyboardTop - self.view.bounds.origin.y;
self.textView.frame = newTextViewFrame;
}
You can get the keyboard size like so :
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardIsUp:) name:UIKeyboardDidShowNotification object:nil];
- (void)keyboardIsUp:(NSNotification *)notification{
CGSize keyboardSize = [self.view convertRect:[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] toView:nil].size;
NSLog(#"%f", keyboardSize.height);
}
[EDIT] Landscape mode
I tried it on the iPas Simulator and it return 264 in portrait mode for a QWERTY keyboard but when you start the app or rotate to landscape mode it returns 1024. So you might need to ask for the width instead of the height in landscape mode...
[EDIT]
Thanks to rob mayoff's comment there is no problem with the landscape mode anymore
[EDIT]
This is not the best way of doing it, but that gives an idea. I'll take a look back at it later
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
CGSize size = [self.view convertRect:self.view.frame toView:nil].size;
CGFloat width = size.width;
CGFloat height = 40;
CGFloat x = 0;
CGFloat y = size.height+40;
aboveKBView = [[[UIView alloc] initWithFrame:CGRectMake(x, y, width, height)] autorelease];
[aboveKBView setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:aboveKBView];
}
- (void)keyboardWillHide:(NSNotification *)notification{
[aboveKBView setHidden:YES];
}
- (void)keyboardWillShow:(NSNotification *)notification{
NSLog(#"keyboardIsUp");
CGSize keyboardSize = [self.view convertRect:[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] toView:nil].size;
CGSize size = [self.view convertRect:self.view.frame toView:nil].size;
CGFloat width = size.width;
CGFloat height = 40;
CGFloat x = 0;
CGFloat y = size.height-(keyboardSize.height+height);
[aboveKBView setFrame:CGRectMake(x, y, width, height)];
[aboveKBView setHidden:NO];
}
I find this page always quite helpful - it shows all important sizes, so it's easy to calculate the size you need:
http://www.idev101.com/code/User_Interface/sizes.html
Try this
in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
and add these methods.
- (void) keyboardWillShow: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y -= 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
- (void) keyboardWillHide: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y += 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
I have a UIViewController that contains a UITableView with custom cells, inside the cell are UILabels, a couple of uneditable UITextView and one editable UITextView. Now, when I tap on one of the UITextView that is near the bottom or the bottom part of the table, the UITextView is covered by the keyboard. I've tried http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html which works great for textfield/textview but not working on the table with custom cell. Any help or suggestions how to go about this?
When your table view contains data entry fields like a UITextField or a UITextView and the table view is long enough to cover the screen, you will have a problem accessing data entry fields that are hidden by the keyboard.
To overcome this problem two solutions are:
The easiest and recommended way is to use a UITableViewController instead of UIViewController, which automatic make sure keypad won't hide the editable field (If possible use this approach to avoid U.I. adjustment inconvenience)
If you use a UIViewController and a UITableView as its subview. You can scroll your UI’s frame by observing the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil]; //Posted immediately prior to the display of the keyboard
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil]; //Posted immediately prior to the dismissal of the keyboard.
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
CGRect keyboardBounds = [[[aNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0); //when keyboard is up, that time just bring your text filed above the keyboard
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0);
[self.tableView scrollToRowAtIndexPath:[self findIndexPathToScroll]
atScrollPosition:UITableViewScrollPositionTop
animated:YES]; //findIndexPathToScroll implementation not shown
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
self.tableView.contentInset = UIEdgeInsetsZero; //Once keyboard is hidden then bring back your table into your original position.
self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero;
[UIView commitAnimations];
}
registerForKeyboardNotifications - call this method when you load the UITableView, ie: viewDidLoad
findIndexPathToScroll - (Implementation not shown) Its your business logic to prepare IndexPath where table view should scroll
removeObserver 'UIKeyboardWillShowNotification' and 'UIKeyboardWillHideNotification' both in dealloc and viewDidUnload
I fixed the issue. Please see my solution below:
1. First declare a global varibale called "activeFileld"
#property(nonatomic,strong)id activeFiled;
2. Create a method called "registerForKeyboardNotifications"
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil]; //Posted immediately prior to the display of the keyboard
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil]; //Posted immediately prior to the dismissal of the keyboard.
}
3. Called the above method in viewWillAppear:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//Register kryboard Notification
[self registerForKeyboardNotifications];
}
4. Call the Delegate method for UitextFieldd Or UitextView
- (void)textFieldDidBeginEditing:(UITextField *)sender {
self.activeField = sender;
}
- (void)textFieldDidEndEditing:(UITextField *)sender{
self.activeField = nil;
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
// save the text view that is being edited
_notes = textView.text;
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
// release the selected text view as we don't need it anymore
_activeField = nil;
}
5.
- (void)keyboardWillShow:(NSNotification *)notification
{
if([_activeField isKindOfClass:[UITextField class]]) {
NSDictionary* info = [notification userInfo];
NSLog(#"Dictionary %#",info);
CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
kbRect = [self.view convertRect:kbRect fromView:nil];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
CGRect aRect = self.view.frame;
aRect.size.height -= kbRect.size.height;
UITextField *textField = (UITextField*)_activeField;
if (!CGRectContainsPoint(aRect, textField.frame.origin) ) {
[self.tableView scrollRectToVisible:textField.frame animated:YES];
}
}else if([_activeField isKindOfClass:[UITextView class]]) {
NSDictionary* info = [notification userInfo];
NSLog(#"Dictionary %#",info);
CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
kbRect = [self.view convertRect:kbRect fromView:nil];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
CGRect aRect = self.view.frame;
aRect.size.height += kbRect.size.height;
UITextView *activeTextView = (UITextView*)_activeField;
if (!CGRectContainsPoint(aRect, textField.superview.superview.frame.origin) ) {
[self.tableView scrollRectToVisible:activeTextView.superview.superview.frame animated:YES];
}
}
}
// Called when the UIKeyboardWillHideNotification is received
- (void)keyboardWillHide:(NSNotification *)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
}
Two solutions:
Preferred: use a UITableViewController instead of a UIViewController as that one will automatically make sure that your keypad won't hide the editable field.
Hacky: How to make a UITextField move up when keyboard is present?
A simple solution. Implement the heightForFooter method, and let it return a value of (say) 100, and when you select the a cell in UITableView, they will simply slide up by that height, and the keyboard will not cover the view.
I've always used a two fold solution for this.
Resize table so it now fits in the smaller area.
Scroll to the cell we want visible. (we needed to re-size the table for this or you'd still wind up being unable to get to the last couple of cells in the table.)
To do this, I register keyboard show/hide events and act accordingly when they get called.
- (void)keyboardWillShow:(NSNotification *)note {
[self updateForKeyboardShowHide:note appearing:YES];
}
- (void)keyboardWillHide:(NSNotification *)note {
[self updateForKeyboardShowHide:note appearing:NO];
}
- (void)updateForKeyboardShowHide:(NSNotification *)note appearing:(BOOL)isAppearing {
// ignore notifications if our view isn't attached to the window
if (self.view.window == nil)
return;
CGFloat directionalModifier = isAppearing?-1:1;
CGRect keyboardBounds = [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat animationDuration = [[note.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
// figure out table re-size based on keyboard
CGFloat keyboardHeight;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation))
keyboardHeight = keyboardBounds.size.height;
else
keyboardHeight = keyboardBounds.size.width;
[UIView animateWithDuration:animationDuration animations:^{
// resize table
CGRect newFrame = table.frame;
newFrame.size.height += [self calculateKeyboardOffsetWithHeight:keyboardHeight] * directionalModifier;
table.frame = newFrame;
} completion:^(BOOL finished){
// scroll to selected cell
if (isAppearing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textFieldInEdit.tag inSection:0];
[table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}];
}
- (CGFloat)calulateKeyboardOffsetWithHeight:(CGFloat)keyboardHeight {
// This depends on the size and position of your table.
// If your table happen to go all the way to the bottom of
// the screen, you'll needs to adjust it's size by the whole keyboard height.
// You might as well ditch this method and inline the value.
return keyboardHeight;
// My table did not go to the bottom of the screen and the position was
// change dynamically so and there was long boring calculation I needed to
// do to figure out how much my table needed to shrink/grow.
}
I am trying to make a UIScrollView scroll when the user starts editing a UITextField and the text field is hidden by the keyboard. I am using an example from the following thread.
How to make a UITextField move up when keyboard is present
I have four UITextFields in my view. When the keyboard is shown for the first time the view does not scroll automatically. If I click another text field with the keyboard shown, the UIScrollView scrolls as intended.
Hiding the keyboard (by tapping the "Done" button) and tapping a UITextField again the same issue occurs: the UIScrollView does not scroll at first but when changing focus to another text field it scrolls perfectly.
Can anyone please help me?
In viewDidLoad I set the size of the scrollView
keyboardIsShown = NO;
CGSize scrollContentSize = CGSizeMake(320, 350);
self.scrollView.contentSize = scrollContentSize;
I register for the keyboard notifications in viewWillAppear
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:self.view.window];
Then I unregister in viewWillDisappear
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
The following two methods are called by the notifications.
- (void)keyboardWillShow:(NSNotification *)n {
if (keyboardIsShown) {
return;
}
NSDictionary *userInfo = [n userInfo];
NSValue *boundsValue = [userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
CGRect viewFrame = self.scrollView.frame;
viewFrame.size.height -= (keyboardSize.height - 50);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
- (void)keyboardWillHide:(NSNotification *)n {
NSDictionary *userInfo = [n userInfo];
NSValue *boundsValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGSize keyboardSize = [boundsValue CGRectValue].size;
CGRect viewFrame = self.scrollView.frame;
viewFrame.size.height += (keyboardSize.height - 50);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = NO;
}
If you want to show the textfeild when keyboard is visible then use the code below. Don't go with the scrollview. If it is compulsory to use a scrollView then neglect this answer.
#define kOFFSET_FOR_KEYBOARD 280.0
- (void)keyboardWillHide:(NSNotification *)notif {
[self setViewMoveUp:NO];
}
- (void)keyboardWillShow:(NSNotification *)notif{
[self setViewMoveUp:YES];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
stayup = YES;
[self setViewMoveUp:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
stayup = NO;
[self setViewMoveUp:NO];
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMoveUp:(BOOL)moveUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect rect = self.view.frame;
if (moveUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
if (rect.origin.y == 0 ) {
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
//rect.size.height += kOFFSET_FOR_KEYBOARD;
}
}
else
{
if (stayup == NO) {
rect.origin.y += kOFFSET_FOR_KEYBOARD;
//rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
}
self.view.frame = rect;
[UIView commitAnimations];
}
Try this methods. Edit it according to your requirement.