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];
}
Related
I'm sorry about my English language.
I tried to find before it acts. But the problem is that ViewController in the landscape and created UIView half of the ViewController. In UIView have UITextView. But now when keyboard appear background in the ViewController scroll down below the keyboard. And see just UIView. If touch space, keyboard will disappear and background comeback. I want to just is move the UIView when keyboard appear.
Thank you very much.
try this
- (void)viewDidAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)note
{
CGRect keyboardBounds;
NSValue *aValue = [note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey];
[aValue getValue:&keyboardBounds];
keyboardHeight = keyboardBounds.size.height;
if (!keyboardIsShowing)
{
keyboardIsShowing = YES;
CGRect frame = view.frame;
frame.size.height -= 168;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3f];
view.frame = frame;
[UIView commitAnimations];
}
}
- (void)keyboardWillHide:(NSNotification *)note
{
CGRect keyboardBounds;
NSValue *aValue = [note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
[aValue getValue: &keyboardBounds];
keyboardHeight = keyboardBounds.size.height;
if (keyboardIsShowing)
{
keyboardIsShowing = NO;
CGRect frame = view.frame;
frame.size.height += 168;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3f];
view.frame = frame;
[UIView commitAnimations];
}
}
This answer looks like it might be what you're looking for.
In short:
Detect when the keyboard appears with UIKeyboardDidShowNotification.
The user info for that notification describes the frame of the keyboard.
Adjust the frame(s) of your view(s) to get them out from under the keyboard.
I have a UIScrollView designed to enable scrolling when the keyboard is up. The positioning of the scroll view is fine in portrait mode; I have positioned it in Interface Builder, and set the contentSize in my code ...
CGSize scrollContentSize = CGSizeMake(360, 221);
self.scrollView.contentSize = scrollContentSize;
However, I am struggling to work out how to change the position of the scrollview so it works effectively when the orientation changes to landscape (and back). Do I somehow need to position it in Interface Builder for landscape(?), and then change the content size in my code dependent on the orientation?
Edit:
Im getting the keyboard size as follows, and changing the content size. This works when i move to Portrait, but the frame is positioned slightly wrong in landscape mode.
(void)keyboardWillShow:(NSNotification *)n{
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
CGRect _keyboardEndFrame;
[[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight;
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
_keyboardHeight = _keyboardEndFrame.size.height;
}
else {
_keyboardHeight = _keyboardEndFrame.size.width;
}
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
viewFrame.size.height -= _keyboardHeight;
if (UIDeviceOrientationIsPortrait(orientation)){
CGSize scrollContentSize = CGSizeMake(360, 221);
self.scrollView.contentSize = scrollContentSize;
}
else if (UIDeviceOrientationIsLandscape(orientation)){
CGSize scrollContentSize = CGSizeMake(520, 275);
self.scrollView.contentSize = scrollContentSize;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
What you want to do is figure out the where the top of the keyboard is relative to the view that contains your scrollView. Fortunately, there is a function in UIView called convertRect:fromView: that will take the frame from one coordinate system and map it to another coordinate system. In your case, you know the frame of the keyboard relative to the main window, but would like to know where the top of the keyboard is relative to the view that contains your scrollView. Once you know where the top of the keyboard intersects with your view, you can modify the height of your scrollView to accommodate.
Below is a snippet of code I use, which I found somewhere online and don't take credit for. In your view controller you want to be notified of keyboard show and hide events:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];
Then implement keyboardWillShow: and keyboardWillHide: like this:
// When the keyboard shows resize self.textView to touch the top of the keyboard.
-(void)keyboardWillShow:(NSNotification *)_notification {
NSDictionary *userInfo = [_notification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
// Here we figure out where the keyboard overlaps with self.view
// self.view contains self.textView
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame fromView:nil];
CGFloat textViewWidth = self.view.frame.size.width;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
self.textView.frame = CGRectMake(0, 0, textViewWidth, keyboardFrame.origin.y);
[UIView commitAnimations];
}
// When the keyboard hides return self.textView to fullscreen
-(void)keyboardWillHide:(NSNotification *)_notification {
NSDictionary *userInfo = [_notification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
self.textView.frame = self.view.frame;
[UIView commitAnimations];
}
The snippet contains some extra stuff to animate the transition in sync with the keyboard animation.
In this snippet I use self.textView, which you will probably want to change to self.scrollView. What's great about this code is that it works in all orientations and on the iPad. Take a look at the code and hopefully it'll be self explanatory.
use this method to check orientation & change content Size of scrollView according to orientation
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
i have used following code to move the screen upwards when we hit on text field ,,this code was working fine with xcode 3 but its not working with xcode 4 ,,its not giving any error but when we touch on the text field screen ill go upwards to a greater height ,,some times wont come back ti original position
- (void)keyboardWasShown:(NSNotification *)aNotification {
if ( keyboardShown )
return;
if ((activeField==tfText[4])||(activeField==tfText[5]))
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_2
CGRect _keyboardEndFrame;
[[aNotification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat keyboardSize;
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
keyboardSize = _keyboardEndFrame.size.height;
}
else {
keyboardSize = _keyboardEndFrame.size.width;
}
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y -= keyboardSize-70;
frame.size.height += keyboardSize-70;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
#else
NSDictionary *info = [aNotification userInfo];
NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y -= keyboardSize.height-70;
frame.size.height += keyboardSize.height-70;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
#endif
viewMoved = YES;
}
keyboardShown = YES;
}
- (void)keyboardWasHidden:(NSNotification *)aNotification {
if ( viewMoved ) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED <= __IPHONE_3_2
CGRect _keyboardEndFrame;
[[aNotification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat keyboardSize;
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
keyboardSize = _keyboardEndFrame.size.height;
}
else {
keyboardSize = _keyboardEndFrame.size.width;
}
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y += keyboardSize-70;
frame.size.height -= keyboardSize-70;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
#else
NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
NSTimeInterval animationDuration = 0.300000011920929;
CGRect frame = self.view.frame;
frame.origin.y += keyboardSize.height-70;
frame.size.height -= keyboardSize.height-70;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
#endif
viewMoved = NO;
}
keyboardShown = NO;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
// Additional Code
}
using following code i am calling the above methods
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasHidden:)
name:UIKeyboardDidHideNotification
object:nil];
}
- (void)viewDidLoad
{
[super 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;
//make contentSize bigger than your scrollSize (you will need to figure out for your own use case)
CGSize scrollContentSize = CGSizeMake(320, 345);
self.scrollView.contentSize = scrollContentSize;
}
- (void)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];
}
- (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.scrollView.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.scrollView 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.scrollView.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.scrollView setFrame:viewFrame];
[UIView commitAnimations];
keyboardIsShown = YES;
}
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
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.