Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 11-15-2008, 05:08 AM   #1 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default [Solved] Keyboard is hiding the view - what to do?

I noticed this in a few apps and it's a really annoying problem.
When I click a textfield the keyboard appears and probably hides the textfield.

I noticed the code in UICatalog, but I don't think that's the best way to do this.
I think the SMS-App is the best example.
It works great!

But how to do this?
I exchanged my view with a scrollview...
But how can I resize it?

I think it's like that:
Code:
-(void)textField: (UITextField)textField DidBeginEditing {
[self resizeViewToFit];
//sth. else here
}

-(void)resizeViewToFit {
self.view.size.heigth -= KeyboardSize;
}
Obviously this doesn't work.
How do I get the keyboard's size and then decrease my view's heigth?

Regards

Last edited by Forsworn; 03-01-2009 at 03:54 AM.
Forsworn is offline   Reply With Quote
Old 11-15-2008, 07:39 AM   #2 (permalink)
New Member
 
Join Date: Aug 2008
Posts: 394
Default

The way I do it is the view my fields are on is a scrollview with a normal contentsize(320x480). When the user selects a textbox to type in I change the context size to it's now longer, I use scrollToRect to move the textbox to the top of the view and then I disable user interaction for the scrollview so they can't actually scroll around. When they close the keyboard I reverse the changes.
__________________
Super Pig
iOwn - Inventory anything and everything.
detz is offline   Reply With Quote
Old 11-15-2008, 11:57 AM   #3 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

Could you give me some code,please?
That would be really great!
Forsworn is offline   Reply With Quote
Old 11-16-2008, 03:53 AM   #4 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

look below...

Last edited by Forsworn; 11-16-2008 at 08:11 AM.
Forsworn is offline   Reply With Quote
Old 11-16-2008, 08:08 AM   #5 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

Okay... here's the working code:

Setup:

Interface:
View:
-NavigationBar
-(ImageView,etc.)
-ScrollView:
.......... -TextFields,etc.

ViewController:
Code:
IBOutlet UIScrollView *scrollView;
Connect:
- The view outlet to your 'main' view (not the scrollview!)
- The textFields' delegates to your viewController
- The scrollView Outlet to your Scrollview

In the implementation you have to add the following delegate methods:

Code:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
	NSLog(@"preparing to show keyboard");
	scrollView.frame = CGRectMake(0,44,320,200); //44:NavigationBar ; 200: Keyoard
	[scrollView scrollRectToVisible:textField.frame animated:YES]; //Oddly enough, it only works with the animation...
	
}
Code:
-(void)textFieldDidEndEditing:(UITextField *)textField {
	NSLog(@"prepare to hide keyboard");
	scrollView.frame = CGRectMake(0,44,320,416); //original setup
}
I hope this will help somebody.

Last edited by Forsworn; 02-10-2009 at 12:36 PM.
Forsworn is offline   Reply With Quote
Old 01-01-2009, 06:31 AM   #6 (permalink)
nocturnalware.biz
 
Join Date: Oct 2008
Location: Sydney, Australia
Posts: 77
Default

I'm implementing this exact feature at the moment and I've run into a problem.

Say there are 6 UITextField objects on screen. When I resize the frame and the keyboard displays, there are maybe a maximum of 3 UITextFields visible in the new resized view. The scrolling and everything works fine, but the problem is that the remaining 3 fields which aren't visible while the keyboard is up all clear their contents when the keyboard disappears again.

Hope that makes sense. Does anyone know what this might be caused by?
sjarman is offline   Reply With Quote
Old 01-01-2009, 10:15 AM   #7 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

This is extremely old and buggy code...
Here's a better way (only for portrait mode):
Code:
-(void)textFieldDidBeginEditing:(UITextField *)textField { //Keyboard becomes visible
	scrollView.frame = CGRectMake(scrollView.frame.origin.x, scrollView.frame.origin.y, scrollView.frame.size.width, scrollView.frame.size.height-215); //resize
}

-(void)textFieldDidEndEditing:(UITextField *)textField { //keyboard will hide
	scrollView.frame = CGRectMake(scrollView.frame.origin.x, scrollView.frame.origin.y, scrollView.frame.size.width, scrollView.frame.size.height+215); //resize
}
Much better way would be to register for "KeyboardWillShow:" and "KeyboardWillHide:" notification.Then you can get the keyboard's height,...

regards

edit:
make sure you set the contentsize!
scrollview.scontentSize = scrollView.frame.size;

Last edited by Forsworn; 01-01-2009 at 11:22 AM.
Forsworn is offline   Reply With Quote
Old 01-01-2009, 11:01 AM   #8 (permalink)
New Member
 
Join Date: Nov 2008
Posts: 123
Default mobile safari keyboard

One of the things I have on my to do list is how to handle a scrollable set of text fields-- think a customer's:

sold to: ....

bill to: ...

ship to: .....

I have these layed-out so that they are on a single, vertically-scrollable view.

When the user touches a text field, the kb pops up and:


1) if the kb does not cover the touched field, this is fine (for now)

2) if the kb covers the touched field, this is bad, but the user can manually scroll to make it visible

3) I plan to add some code so the display will automatically scroll so that the field touched in 2 is above the kb (prolly vertically centered).

I don't particularly like the choices for 2 & 3 as both might confuse the user.

The iPhone mobile safari browser handles this problem in a more intuitive way:

It adds a submenu above the keyboard that has buttons for previous, next and done.

This essentially provides the tab and back-tab keys that are missing from the kb

It gives the user an intuitive way to tab (forward or back) through a lot of text fields.

IMO, Apple should provide this tab-key menu (and functionality) as an option... but they don't.

Also, there doesn't seem to be an easy way to programatically determine the sequence and position of the various text fields so I can write some generalized code to tab/scroll between fields.

The only way I can think to do this is parse the xib file and extract the frame, kb type, etc, info for the text fields, then write my own tab submenu. While not too difficult, this is a pita!

Has anyone done this?

TIA

Dick
dicklacara is offline   Reply With Quote
Old 02-10-2009, 09:11 AM   #9 (permalink)
CAM
Registered Member
 
Join Date: Feb 2009
Posts: 157
Default

Hey can someone post some source code?
CAM is offline   Reply With Quote
Old 02-10-2009, 11:15 AM   #10 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 253
Default

I came up with a less sophisticated approach for a recent app. I have a label that is normally hidden that resides in the upper half of the screen. You can't see it, but when you try to type in a text field it becomes visible and it echoes what the user types. It's sub-optimal in that it looks totally different than a text field, but it works ok.
zhyla is offline   Reply With Quote
Old 02-10-2009, 12:37 PM   #11 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

You can simply use UIScrollView's scrollRect:toVisible: method to do so.
Forsworn is offline   Reply With Quote
Old 02-10-2009, 01:14 PM   #12 (permalink)
CAM
Registered Member
 
Join Date: Feb 2009
Posts: 157
Default

Quote:
Originally Posted by Forsworn View Post
You can simply use UIScrollView's scrollRect:toVisible: method to do so.
Can you give a code snipit. I don't understand completely.
CAM is offline   Reply With Quote
Old 02-10-2009, 01:29 PM   #13 (permalink)
Registered Member
 
Forsworn's Avatar
 
Join Date: Oct 2008
Location: Germany
Posts: 504
Default

Code:
[myScrollView scrollRectToVisible:myLabel.bounds animated:YES];
It's easy.
Forsworn is offline   Reply With Quote
Old 06-24-2009, 09:15 AM   #14 (permalink)
iPhone Developer
 
Join Date: Sep 2008
Location: Canada
Posts: 149
Default

I can move the view around using a scroll view. But what I can't do is make the user actually able to scroll around himself. I'd like to give the user the option to scroll up to a different field to edit.

Any ideas?
Henning is offline   Reply With Quote
Old 01-10-2010, 10:49 AM   #15 (permalink)
Registered Member
 
Join Date: Jun 2009
Posts: 133
Default

I do this to animate the view up and down when the keyboard is required.

In the viewDidLoad method I set up a few observers:

Code:
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then the two methods that will be called by the notifications are:

Code:
- (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];
}
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.

However I have a problem!

I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.

I cannot figure out how to check in the methods which control triggered the notification and process accordingly?

I have tried passing the name of the objects in the addObserver calls but the no notifications occur!

Is there a way to query which control is current selected on the screen?
ghanalupo is offline   Reply With Quote
Old 03-13-2010, 06:46 AM   #16 (permalink)
Registered Member
 
Join Date: Mar 2010
Location: Norway
Posts: 49
Default

Quote:
Originally Posted by ghanalupo View Post
I do this to animate the view up and down when the keyboard is required.

In the viewDidLoad method I set up a few observers:

Code:
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then the two methods that will be called by the notifications are:

Code:
- (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];
}
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.

However I have a problem!

I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.

I cannot figure out how to check in the methods which control triggered the notification and process accordingly?

I have tried passing the name of the objects in the addObserver calls but the no notifications occur!

Is there a way to query which control is current selected on the screen?

Yeah, NSNotification.object returns the object associated with the notification. So you can simply check if the object is one or more of the fields you dont want to autoscroll for.
teek is offline   Reply With Quote
Old 03-26-2010, 11:43 PM   #17 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 201
Default

I just do a check like this:

Code:
- (void)keyboardWillShow:(NSNotification *)notif
{
if (([textField2 isFirstResponder])
{

        [self setViewMovedUp:YES];



}}
not_too_shabby is offline   Reply With Quote
Old 04-15-2011, 09:12 AM   #18 (permalink)
Registered Member
 
Join Date: Apr 2011
Posts: 1
Smile AKeyboardAwareUIViewControll

Hi,

I had the same problem and wrote a useful class that solves it just by subclassing it for every view controller you need to be aware of the keyboard:

Solving the iOS keyboard hiding views once and for all: AKeyboardAwareUIViewController | Compiotrs developer blog

Hope it helps
PiotrB is offline   Reply With Quote
Old 05-28-2011, 02:19 PM   #19 (permalink)
Registered Member
 
Join Date: May 2011
Posts: 1
Default

the following blog entry shows a complete example project of how to handle the keyboard hiding issue:

TC Development: Simple UIScrollView

Another good reference is the apple documentation on handling the keyboard:
Loading…
tc-development is offline   Reply With Quote
Old 09-01-2011, 11:14 AM   #20 (permalink)
learning while doing
 
Moe2392's Avatar
 
Join Date: Aug 2011
Location: Ontario
Posts: 31
Default

Quote:
Originally Posted by ghanalupo View Post
I do this to animate the view up and down when the keyboard is required.

In the viewDidLoad method I set up a few observers:

Code:
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then the two methods that will be called by the notifications are:

Code:
- (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];
}
So when a textfield or textview are touched the screen scrolls up automatically as the keyboard comes in from bottom.

However I have a problem!

I have a textfield at the top of the screen that does not require the screen to be scrolled up when keyboard appears but below that I have a textview that does need the screen scrolling up.

I cannot figure out how to check in the methods which control triggered the notification and process accordingly?

I have tried passing the name of the objects in the addObserver calls but the no notifications occur!

Is there a way to query which control is current selected on the screen?

You probably figured this out long ago in your own way, but what i did was i just made if blocks around the code and duplicated it in each statement. So i have two buttons, the first on i say if [UItextfield isFirstResponder]{}
then else if [UItextfield2 isFirstResponder] {//make it animate up and then down}

My problem with this is that when I click on one textfield, then on the other without clicking done on the keyboard, it will not animate up for the first one, then just animate down when i leave the second textfield. Is there a way to just set the screen back to original? I'm actually going to try and make it so that on the animation which moves things back to normal, i just put in the original perameters of the screen (just came up with it as i was typing). So i will set the y back to what it should be to make the screen sit in its place.

//this is what i put in and it moves the screen back to its original place.
//it is not +=, but just = now
rect.origin.y = 0;

Last edited by Moe2392; 09-01-2011 at 11:17 AM. Reason: adding what i did.
Moe2392 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 235
16 members and 219 guests
@sandris, ADY, Alsahir, dacapo, Dani77, djohnson, HemiMG, jansan, JasonR, MarkC, mer10, prchn4christ, ryandb2, smethorst, tomtom100
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,882
Threads: 89,228
Posts: 380,762
Top Poster: BrianSlick (7,129)
Welcome to our newest member, jansan
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:00 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0