Deactivate view moveUp when showing keyboard on iOS8 - ios

In my application, I have a signing up form, with some textFields (Email, password etc ...), when I begin typing somewhere in these textFields (The keyboard is shown), my View moves Up, and I'm not able to see what's being typed in my text field.
This problem occurs only with iOS8.
If some one knows how to block this os feature, i'll be thankful.
Regards.

Here is my code for managing issues related to Keyboard appearance and disappearance.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self registerForKeyboardNotifications];
}
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark - Keyboard Delegate
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//to overcome the bug with keyboard height for os7 and earlier
if (![UIDeviceHardware isOS8Device]) {
CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
kbRect = [self.view convertRect:kbRect fromView:nil];
kbSize = kbRect.size;
}
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[_scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
You can pick activeField from UITextfield Delegate.

This will be useful to you..
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == (UITextField *)[self.view viewWithTag:TEXTFIELD_MOBILE_TAG])
{
CGRect selfframe = CGRectMake([self.view viewWithTag:VIEW_PARENT_TAG].frame.origin.x, [self.view viewWithTag:VIEW_PARENT_TAG].frame.origin.y - 80, [self.view viewWithTag:VIEW_PARENT_TAG].frame.size.width, [self.view viewWithTag:VIEW_PARENT_TAG].frame.size.height);
[UIView animateWithDuration:0.3 animations:^{ [self.view viewWithTag:VIEW_PARENT_TAG].frame = selfframe;}];
[textField becomeFirstResponder];
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == (UITextField *)[self.view viewWithTag:TEXTFIELD_MOBILE_TAG])
{
CGRect selfframe = CGRectMake([self.view viewWithTag:VIEW_PARENT_TAG].frame.origin.x, [self.view viewWithTag:VIEW_PARENT_TAG].frame.origin.y + 80, [self.view viewWithTag:VIEW_PARENT_TAG].frame.size.width, [self.view viewWithTag:VIEW_PARENT_TAG].frame.size.height);
[UIView animateWithDuration:0.3 animations:^{ [self.view viewWithTag:VIEW_PARENT_TAG].frame = selfframe;}];
[textField resignFirstResponder];
}
}

Related

Keyboard move up and down with many subviews with uiTextfield

I need to move a keyboard up and down. I have many subviews with many uiTextfields. These subviews has one superview and this superview is in the scroll view.
I can't move up a view using below code:
- (void) keyboardWasShown:(NSNotification *)notification{
NSDictionary *info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey]CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0);
self.Scroll_view.contentInset = contentInsets;
self.Scroll_view.scrollIndicatorInsets = contentInsets;
}
- (void) keyboardWillBeHidden:(NSNotification *)notification{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.Scroll_view.contentInset = contentInsets;
self.Scroll_view.scrollIndicatorInsets = contentInsets;
}
This code working fine when i place all the UITextfields in the ScrollView(Not into the subviews), But i need to do with subview and also move keyboard up and down.
How can i move a keyboard up and down while press keyboard Next/Return key?
Try This:
- (void)animateViewUpToTargetYOrigin:(CGFloat)yValue
{
[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidChangeFrameNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
CGFloat yOrigin = 0;
CGFloat keyboardYOrigin = [[[note userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
if (yValue > keyboardYOrigin) {
yOrigin = yValue - keyboardYOrigin;
}
[UIView animateWithDuration:0.3f animations:^{
self.view.frame = CGRectMake(self.frame.origin.x, -yOrigin, self.frame.size.width, self.frame.size.height);
}];
}];
Using this code you only need to call this method in textfield didbeginediting, and pass the yOrigin(textfield)+height(textField) as y value in it.
If you textFields are in Scrollview or any sub view convert their frame values in respect to self.view before sending Y value.
E.g:
CGRect textFieldRectWithRespectToSelfView = [textField.superview convertRect:textField.frame toView:self.view];
[self.view animateViewUpToTargetYOrigin: textFieldRectWithRespectToSelfView.orgin.y + textFieldRectWithRespectToSelfView.size.height];
When you call [textField resignFirstResponder], self.view comes back to its original position. This happens because the UIKeyboardDidChangeFrameNotification always keeps listening to keyboard frame changes.
I do have a demo project in github as an example please refer to it:
https://github.com/subhajitregor/ViewMoveUpExample
In viewDidLoad method
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
// the keyboard is hiding reset the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y += 150;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
// the keyboard is showing so resize the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y -= 150;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}

Calculating how much to scroll up from keyboard height UITableview

I have UIScrollView and UITextField like this. I know how to get keyboard height shown in my self.view. However, UITextField position will not be fixed at particular position since user may scroll.
How can I move up the uitextfield only if it is covered by keyboard? Do I need to use CGPoint and convertPoint? May I know how to do?
You should use UITextFieldDelegate.
Here is an example how you can implement it :
-(void)textFieldDidBeginEditing:(UITextField *)textField {
if(!moved) {
[self animateViewToPosition:self.view directionUP:YES];
moved = YES; }
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
if(moved) {
[self animateViewToPosition:self.view directionUP:NO];
moved = NO;
}
[textField resignFirstResponder];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if(moved) {
[self animateViewToPosition:self.view directionUP:NO];
}
moved = NO;
return YES;
}
-(void)animateViewToPosition:(UIView *)viewToMove directionUP:(BOOL)up {
const int movementDistance = -260; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: #"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
viewToMove.frame = CGRectOffset(viewToMove.frame, 0, movement);
[UIView commitAnimations];
}
// 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.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
it may help if you some one wants to try but it may not the best solution
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect actualframe = [textField convertRect:[textField bounds] toView:self.view];
if ((actualframe.origin.y) >= (self.view.frame.size.height-keyboardheignt))
{
CGRect scrollfrm = [textField convertRect:[textField bounds] toView:tableview];
[tableview setContentOffset:CGPointMake(0, scrollfrm.origin.y) animated:YES];//60
}
}
you have to use the content inset if the textfield is last row of the table

Push view up when keyboard shown

I need to push the entire up (it has scrollview) when keyboard shown
but can't seem to get it working with this code.
All the code being hit but it just doesn't push up the view.
I am following the example here.
http://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW7
- (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.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
self.activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
self.activeField = nil;
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.activeField.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, self.activeField.frame.origin.y-kbSize.height);
[self.scrollView setContentOffset:scrollPoint animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
I imagine that the keyboard appears when the user clicks on a textfield right?
you have to use the method of the delegate for the UITextField.
in your viewController.h add UITextFieldDelegate and in your .m insert:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (void) animateTextField: (UITextField *)textField up: (BOOL) up
{
const int movementDistance = 140; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
add also these methods:
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[yourTextField resignFirstResponder];
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField {
[yourTextField resignFirstResponder];
Return YES;
}
you can use scrollView in your view. then put all other subviews in the scrollView and then set the content offset of scrollView in "textfieldShouldBeginEditing" method.
[scrollView setContentOffset:CGPointMake(0,160)]; // this is just an example
hope this will help you.
I had the same problem! Instead I decided to use a tableview. Insert your UITextFields in the TableViewCells and it will scroll up automatically when keyboard comes up!

iOS - UIScroll on Keyboard popup to textfield on when textfield is inside subview

I used code to make the screen scroll when the keyboard is covering up a textfield.
I have a list of textfields, and i started putting each inside of its own uiview for styling and organizational purposes.
now my code only works when i begin actually typing in the textfield. this is the monstrosity I copied from apple. Note: I added one parameter to
registerForKeyboardNotifications so that I could include this in a parent class and call it from anywhere
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications:(UIScrollView *)scroll
{
_scroller = scroll;
[[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.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSLog(#"hey");
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, _activeField.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, _activeField.frame.origin.y-kbSize.height);
[_scroller setContentOffset:scrollPoint animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
_activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
_activeField = nil;
}
I have narrowed down the problem to this part in the viewcontroller
for (id subView in _tpnScroll.subviews)
{
if ([subView isKindOfClass:[UIView class]]) {
UIView *thisView = subView;
for(id textfield in thisView.subviews){
if([textfield isKindOfClass:[UITextField class]]){
[textfield setDelegate:self];
}
}
}
}
the original code was
for (id subView in _tpnScroll.subviews){
if ([subView isKindOfClass:[UITextField class]]) {
[subView setDelegate:self];
}
}
in the first example. im looping through my UIViews, and locating the UITextfields, and setting the delegate to self (this part I don't totally understand, still trying to understand the concept of a delegate)
in the second example, the textfields are located directly on the scrollview so i just loop through them directly.
sorry if this was wordy.
Try replacing keyboardWasShown with this.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSLog(#"hey");
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
_scroller.contentInset = contentInsets;
_scroller.scrollIndicatorInsets = contentInsets;
// the scroll view will only scroll if the text field is not fully visible
// no need to check if it is actually covered
[_scroller scrollRectToVisible:[_scroller convertRect:_activeField.bounds fromView:_activeField]
animated:YES];
}
Converting the text field's bounds to the scroll view's coordinate system makes sure that it works if the text field is inside the scroll view even if it is not directly inside it.

Moving form content which is located under the keyboard

I am using UITableView, where each cell contains a UITextField, and using Apple official example, I wish to perform goal, moving the active field above the keyboard if it's already hidden. However, the form doesn't move although the UITableView is scroll eabled. Here is my relevant code, please help me pointing on what seems to be missing/wrong:
#interface ViewController (){
UITextField *activeField;
}
- (void)viewDidLoad
{
//....
objTableView.scrollEnabled=YES;
//....
}
#pragma mark - Keyboard notifications
// 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.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
objTableView.contentInset = contentInsets;
objTableView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
[objTableView setContentOffset:scrollPoint animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
objTableView.contentInset = contentInsets;
objTableView.scrollIndicatorInsets = contentInsets;
}
#pragma mark - UITextFieldDelegate protocol method
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
Try this code:
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
CGRect rc = [activeField bounds];
rc = [activeField convertRect:rc toView:objTableView];
[objTableView scrollRectToVisible:rc animated:YES];
}

Resources