iOS: How to adjust height of area covered by keyboard in iOS - ios

Im curious about a feature in iOS. Please help me out here if you can.
Scenario: I am using a text box where name is entered. Its on lower half of the screen. Just below the text box is a label which displays the number of characters remaining(e.g.like in a twitter feed).
Problem: When i place the text box in upper half of the screen. both the text field and label are visible. But when I place them in lower half, the apple keyboard covers the label part.
Is there a way where I control the area covered in such a way that the label below is also visible?
I hope I have made myself clear enough.
Thanks.

Here i have used delegate method for UITextView Same way you can do for UITextField
-Here in this code when user starts entering values in textview it makes your view's hight lesser then its original with animation
-When user Ends Entering values, it will make your view's size original size.
-(void)textViewDidBeginEditing:(UITextView *)textView
{
CGRect frame = self.view.frame;
frame.origin.y = -100;
[self.view setFrame:frame];
[UIView commitAnimations];
}
-(void)textViewDidEndEditing:(UITextView *)textView
{
CGRect frame = self.view.frame;
frame.origin.y = 0;
[self.view setFrame:frame];
[UIView commitAnimations];
}
If you want to know about delegates this link helps you

Well in that case you have to move the textbox when the keyboard pops up.You can have the notification registered to know when the keyboard pops up and a scrollview to scroll the whole content up the screen can do the job for you
See this question,It explains well how to manage something like this

AFAIK You can't control the size of iOS native Keyboard, all you can and should be doing is, making them a subivew of a scroll view and scroll it up.
So the usual practice go something like this.
Subscribe to the Keyboard notification. UIKeyboardWillShowNotification
In the method which the Notification listener will be invoking, set the scrollView's content size accordingly and set the content offset.
self.scrollView.contentSize = CGSizeMake(320, 267);
self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, localKeyboardFrame.size.height, 0);
[self.scrollView scrollRectToVisible:<rect of view you want to scroll to> animated:YES];
Undo the changes when the keyboard hides, with the help of appropriate notification.UIKeyboardWillHideNotification
self.scrollView.contentInset = UIEdgeInsetsZero
And here is iOS Human Interface Guide's explanation on it.

Add following to your viewDidLoad Method
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showKeyboard) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(hideKeyboard) name:UIKeyboardWillHideNotification object:nil];
And after that-- Declare the following 2 methods in your .m file
-(void)showKeyboard {
[UIView beginAnimations:#"slide" context:nil];
[UIView setAnimationDuration:0.3];
self.view.transform = CGAffineTransformMakeTranslation(0, -100);
[UIView commitAnimations]; }
-(void)hideKeyboard {
[UIView beginAnimations:#"slide" context:nil];
[UIView setAnimationDuration:0.1];
self.view.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations]; }

Related

Move UIToolBar above keyboard on screen with UIScrollview

I have a screen within an iPhone app that consist of a UITextView. This text view is contained within a UIScrollView. The purpose of the screen is for the user to type in text, and to optionally attach an image to what he is writing. Therefore, the screen also has a UIToolbar with a camera button at the bottom of the screen. The structure of the screen is as follows:
-View
--UIScrollView
---UITextView
--UIToolbar
---UIButton
When the user navigates to this screen, the viewDidAppear method assigns first responder to the uitextview element, so the keyboard shows up, which hides the toolbar and the camera button.
I would like the entire toolbar to re-draw itself right above the keyboard, and to position itself again at the bottom of the screen when the keyboard hides.
I have found related posts on SO (like this one). However, such methods introduce undesired behaviours. For example, implementing the solution in the article above, the toolbar does move with the keyboard, but the UIScrollView gets its frame.origin.y coordinate shifted way above the top of the screen, so it's impossible for the user to see what he is typing.
I have also tried to reset the frame of the toolbar, by adding it as an IBOutlet and using cgrectmake to reposition it. However, after several tries, the toolbar remains stuck at the bottom of the screen and hidden by the keyboard:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:<#(UIViewAnimationCurve)#>]
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.keyboardToolbar.frame.origin.y - 280;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
I have tried several iterations similar to the code above and they all fail at repositioning the toolbar.
So in short, what is the right way to float a toolbar right on top of a keyboard in a screen whose space is completely utilised by a uitextview element?
Thanks to RoryMcKinnel for the pointer. As the article referenced is in Swift, I thought I might paste the solution that worked for be on ObjC
- (void)keyboardWillShowNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertedKeyboardFrame = [self.view convertRect:keyboardEndFrame fromView:self.view.window];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = CGRectGetMaxY(self.view.bounds) - CGRectGetMinY(convertedKeyboardFrame);
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}
Bear in mind, this code did make the toolbar move as required, but the toolbar was not visible at all. It turned out that it was being hidden behind the UIScrollView. This was easily fixed by shifting the order between the scroll view and the toolbar element in the IB hierarchy.
The method above works for the keyboardWillShow event. You'll need to add the corresponding one for when the keyboard hides, like this:
- (void)keyboardWillHideNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = 0.0f;
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}

Move View up/down with Keyboard ios

I am working on a chat application similar to whatsapp etc. It has a tableview in view controller and a text field and button in the bottom toolbar. I came across the various question on sliding the view upwards and using this link I managed to slide the view upwards. However I want to dismiss the keyboard and the view comes down and fits the screen .I tried using tap gesture and click on return button but nothing seems to work. How do I do make the view slide down and keyboard disappear?
Moreover how can i change the width of text field so that multiple lines can appear when the user is writing the message?
you can add tap gesture event to tableview cell and also you can use touch event method when user click on tableview then according to keyboard previous state you can display or hide keyboard. Hope this will help to u.
Use textFieldShouldReturn to resign first responder status (dismiss the keyboard) and slide the view up.
Personally I do it this way:
I register for notifications to know when the keyboard will be shown, and when it will be hidden.
When the keyboard appears, I set the view insets to include the size of the keyboard.
Slide the view up
When the keyboard will disappear, I set the insets to zero.
TextField Delegate Method to hide the keyboard when the Return button is tapped
-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
[textField resignFirstResponder];
return NO; // We do not want the UITextField to insert line-breaks.
}
Register for keyboard appear/disappear notifications
- (void)viewDidLoad
{
...
// Register for notifications for when the keyboard will appear and disappear
[self registerForKeyboardNotifications];
}
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
// Original code for this part here: http://stackoverflow.com/a/16044603/4518324
- (void)keyboardWasShown:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.view.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
- (void)keyboardWillBeHidden:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.view.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
} completion:nil];
}
I have created sample code that involves resizing the view when they keyboard is shown or dismissed.
https://github.com/gingofthesouth/KeyboardHideShow
I got it right . I had another method called out when keyboard is dismissed which fit the view frame as per requirement which is View.frame-keyboard.frame.height. Thanks anyways!:)

iOS 8 UIView not moving up when keyboard appears

I am developing a chat app which has UITableView and a UIView containing a UITextField and a UIButton in it. I am using the following code to move the UIView up when keyboard appears.
(void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary* info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = self.inputView.frame;
UIInterfaceOrientation orientation = self.interfaceOrientation;
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
frame.origin.y -= kbSize.width;
else
frame.origin.y -= kbSize.height;
self.inputView.frame = frame;
;
}];
}
This code is working fine until iOS 7, but in iOS 8 UIView is not displaying above the keyboard.
Can anyone please suggest what could be the possible issue, or is there anything that has changed in iOS 8?
Your code seems to be correct but i will prefer using UIKeyboardDidChangeFrameNotification or UIKeyboardWillChangeFrameNotification because these will tell you the change in keyboard frame when predictive text bar gets up or down when keyboard is in view.
In your ViewDidLoad add this
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardFrameDidChange:)
name:UIKeyboardDidChangeFrameNotification object:nil];
and then paste this method in your ViewController
-(void)keyboardFrameDidChange:(NSNotification*)notification{
NSDictionary* info = [notification userInfo];
CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
[yourView setFrame:CGRectMake(0, kKeyBoardFrame.origin.y-yourView.frame.size.height, 320, yourView.frame.size.height)];
}
This will handle all your keyboard cases like when its up or down or change in its frame with predictive text bar
and also remove observer when you are leaving your view
The accepted Answer is almost right. To match your view's animation to that of the keyboard you want to use the UIKeyboardWillChangeFrameNotification rather than the UIKeyboardDidChangeFrameNotification. That way the animations you kick off will precisely match that of the keyboard. Here's some code to do the entire thing. I use the animation of the keyboard to drive the animation of my autolayout constraint constants, but you can easily adapt this to animate an entire view frame. (Note, we have to use the old school style animations to hook into the UIKeyboardCurveInfoKey which provides an animation curve exactly matching the keyboard animation.
In viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardFrameDidChange:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
In ViewController:
- (void)keyboardFrameDidChange:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat height = kKeyBoardFrame.size.height;
[self.view removeConstraints:self.verticalButtonConstraints];
NSDictionary *metrics = #{#"height" : #(height)};
NSDictionary *views = #{#"nextButton" : self.nextButton};
self.verticalButtonConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V: [nextButton(52)]-(height)-|" options:0 metrics:metrics views:views];
[self.view addConstraints:self.verticalButtonConstraints];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.view layoutIfNeeded];
[UIView commitAnimations];
}
I just ran into this and made a discovery I thought I would share. In iOS 8 layout passes for the sub views of the main view will be done whenever the keyboard is about to appear or about to go away. These passes do not get done on iOS 7. So if you try to animate a sub view of the main view in keyBoardWillShow or keyboardWillChangeFrame the animation will get undone by the layout pass and your sub views that you tried to animate will move back to their original position. That is why keyboardDidChangeFrame works to animate the subviews and keyboardWillChangeFrame does not.
Something odd I noted as well is the timing of when these calls are made. It seems the first time that the keyboard appears after the app is launched, the call to keyboardDidChangeFrame happens too late to be able to animate with the keyboard so they slide up together, but on second and subsequent times the keyboard shows, the call to keyboardDidChangeFrame happens sooner and it seems you can actually animate the views along with the keyboard.
I must note that I am using C# and Xamarin as my development platform for iOS, so this may be different when using Swift or Obj-C.
You can use an accessoryView, which will attach itself to the top of the keyboard. Alternatively, if you want more power over customization, you can use notifications as explained by #pankaj_wadwha to fetch the frame information. Bonus: you can also get the animation information (such as speed) so your view moves alongside the keyboard perfectly.

Moving Content That Is Located Under the Keyboard [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 a question concerning "Moving Content That Is Located Under the Keyboard".
I have a simple "sign in" view with 2 UITextFields (username and password) and a sign in button.
When the user taps on one of those text fields the keyboard appears and obscurs the sign in button and the password text field.
So I implemented the solution proposed by Apple and one other (see links below) :
https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
http://ios-blog.co.uk/tutorials/how-to-make-uitextfield-move-up-when-keyboard-is-present/
But the problem is that the keyboard moves first and it's only when the keyboard has finished to move that the 2 UITextFields and the sign in button move. Thus it's not the best solution for User Experience...
Do you know I can move the keyboard and the 2 UITextFields at the same time ? Like on the iOS Facebook login page.
Thanks !
Well, you can do this in 2 ways: the easy way, and the hard way.
Easy way: Instead of a ViewController, use a TableViewController and create custom cells that contain the text fields. The TableViewController will take care of moving the view up for you when the keyboard goes up. Then all you have to worry about is to dismiss the keyboard whenever you want the keyboard to go away.
The hard way: Use a ViewController.
In order for this to work you need to have 2 notifications, like this ones (place this inside your viewDidLoad method):
// Keyboard notifications so things can move up when the keyboard shows up
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
Then you need to create the 2 methods you're calling in the NotificationCenter, to actually perform the movement of the screen:
- (void) keyboardWillShow: (NSNotification*) aNotification
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] bounds];
rect.origin.y -= 150;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
// Call this to make the keyboard move everything down
- (void) keyboardWillHide: (NSNotification*) aNotification
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
if (rect.origin.y == -150)
{
rect.origin.y += 150;
}
[[self view] setFrame: rect];
[UIView commitAnimations];
}
In this code, the value of 150 is an arbitrary number of points that the keyboard will go up/down. You can change it or do some fancy calculation to get a percentage of the screen regardless of the screen size.
Hope it helps!
In this case, you should intercept the UIKeyboardWillShowNotification notification and offset your content animately with an animation block.
[UIView animateWithDuration:0.5 animations:^{
// your own animation code
// ...
} completion:nil];`
The same is for the UIKeyboardWillHideNotification notification.
Of course, if you are scrolling the content with an already-animated method, you can just put that without the need of an animation block.
Just shift content when UIKeyboardWillShowNotification is received. Instead of UIKeyboardDidShowNotification.
UPDATE
Also if you need to add animation you could use userInfo from keyboard notification to fetch keyboard height, speed of emerging and animation curve.
So this code should react for UIKeyboardWillShowNotification:
[UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] delay:0.0f options:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] intValue] animations:^{
// TODO: shift content here
} completion:nil];
Also you need something similar for UIKeyboardWillHideNotification. Difference would be just direction of shifting inside animations block.

Trouble setting UIKeyboard accessory view

I have an instance of UIToolbar that contains a UITextField inside. I'd like to set the toolbar at an accessory view for the UITextField it contains.
The way I do this is as follows:
[myTextView setInputAccessoryView:myToolbar];
When I compile and run the code, the entire keyboard disappears when I press on the text field. I specifically made sure I am setting the inputAccessoryView and not the inputView. It seems like the whole input view just got replaced, without any explicit direction to do so.
Does anyone know a way to fix this?
It's generally not good to put a text field in an input accessory view... What would be better is if you put the toolbar along the bottom of your view and then use UIKeyboardWillChangeFrameNotification to move the toolbar with the keyboard...
In your viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
And somewhere in your view controller's code:
-(void) keyboardWillChange:(NSNotification*)notify {
CGRect endFrame;
float duration = [[[notify userInfo] valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
[[[notify userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&endFrame];
endFrame = [self.view convertRect:endFrame fromView:nil];
float y = (endFrame.origin.y > self.view.bounds.size.height ? self.view.bounds.size.height-44 : endFrame.origin.y-44);
[UIView animateWithDuration:duration animations:^{
toolbar.frame = CGRectMake(0, y, self.view.bounds.size.width, 44);
}];
}

Resources