1
votes

I created new Xcode single view project. In interface builder, I added a UIScrollView to cover complete view. Over this scrollview, I added a UITextField. The resulting UI looked like this: enter image description here

Note that the scrollview does not scroll at this point as the content takes only the size of view and not greater than it.

Now for bringing UITextField on top of keyboard while editing, I followed the way described by Apple on Managing The Keyboard page. After doing this, it gave me expected behavior which brought the text field right above keyboard on editing begin as shown in following screenshot: enter image description here

Now, after calling [textfield endEditing:YES], the keyboard hides itself, but the textfield does not return to its original place. It return to the place just little above its original place and now the scroll view becomes scrollable as if little height was added to it:

enter image description here

Notice the scroll bar in the above screenshot!

I want help in bring back the original behavior of the view after editing ends (when keyboard hides) i.e. the textField to return to exact same place and scroll should be happening as it was not happening before editing begin.

Project URL: - https://github.com/therohansanap/keyboard.git

6
you can make a global int to store the amount that u push it up, and on the UIKeyboardWillHideNotification selector, use it to push down the same amountTj3n

6 Answers

1
votes
You need adjust scrollview contentOffset textFieldDidBeginEditing and textFieldDidEndEditing.
or 
One controller is available for scrollview auto scroll.

https://github.com/simonbs/BSKeyboardControls

1
votes

I think the official way specified by Apple here is easiest and best way to keep this functionality working.

0
votes

You can do something similar without Using Keyboard notifications as well. As you may know that we have TextField delegate methods , we can use those to set scrollView contentOffset and acquire the same behaviour

- (void)textFieldDidBeginEditing:(UITextField *)textField{
    scrollView.contentOffset = CGPointMake(0, textField.center.y-80); // you can change 80 to whatever which fits your needs
}

the above method sets contentOffset Value of scroll view and your textFiled moves up, while the textField resignFirstResponder the below delegate method gets called, where you can set back the contentOffset value

- (void)textFieldDidEndEditing:(UITextField *)textField{
       scrollView.contentOffset = CGPointMake(0,-80);
}

Note: you need to make every text field in your view to have their delegate as your UIViewController instance. You also need need your UIViewController to adopt UITextFieldDelegate

0
votes

Took a look at your code, you dont need to change the content insets etc when trying to position the scroll view. You just need to modify the content offset property.

Here is the modified code :

@interface ViewController () {
UITextField *activeField;
CGPoint scrollViewOldPosition;
}

Modify the keyboardWasShow as follows :

// Called when the UIKeyboardDidShowNotification is sent.
 - (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;


CGFloat someSpaceBetweenKeyBoardAndField = 20.0;
scrollViewOldPosition = self.scrollView.contentOffset;

self.scrollView.contentOffset = CGPointMake(0, kbSize.height - (self.view.frame.size.height - activeField.frame.origin.y - activeField.frame.size.height) + someSpaceBetweenKeyBoardAndField);
}

Keyboard will be hidden method :

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.scrollView.contentOffset = scrollViewOldPosition;
}
0
votes

Not the best code ever but it have some more features u can use, anything with _ is global variable

//Handle notification when keyboard appear
- (void)keyboardOnScreen:(NSNotification *)notification
{
    if (_isKeyboardShow) {
        return; //If keyboard is showing then return
    }
    _keyboardHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
    [self animateTextFieldUp: YES];
    _isKeyboardShow = YES; 
}

//Handle notification when keyboard hide
- (void)keyboardOffScreen:(NSNotification *)notification
{
    if(!_isKeyboardShow) return;
    [self animateTextFieldUp: NO];
    _isKeyboardShow = NO;//Missed this line
}

//Push view up with animation when keyboard show
- (void) animateTextFieldUp: (BOOL) up
{
    UITextField *textfield = [UIResponder currentFirstResponder];
    CGPoint windowPoint = [textfield convertPoint:textfield.bounds.origin toView:self.view];
    int movementDistance;
    CGPoint point = [_mainScrollView contentOffset];

    //Push up only when blocked by keyboard
    if (windowPoint.y + textfield.frame.size.height >= self.view.frame.size.height - _keyboardHeight) {
        movementDistance = windowPoint.y - (self.view.frame.size.height - _keyboardHeight) +  textfield.frame.size.height + 10;
        _oldMovementDistance = movementDistance;
        int movement = (up ? -movementDistance : movementDistance);
    [_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
    }
    else { //Push view down the same amount
        int movement = (up ? -movementDistance : _oldMovementDistance);
        [_mainScrollView setContentOffset:CGPointMake(0, point.y - movement) animated:YES];
        _oldMovementDistance = 0;
    }
}
0
votes

move UITextField and UITextView out of the way of the keyboard during editing:

For non-UITableViewControllers, drop the TPKeyboardAvoidingScrollView.m and TPKeyboardAvoidingScrollView.h source files into your project, pop a UIScrollView into your view controller's xib or storyboard, set the scroll view's class to TPKeyboardAvoidingScrollView, and put all your controls within that scroll view. You can also create it programmatically, without using a xib - just use the TPKeyboardAvoidingScrollView as your top-level view.

For use with UITableViewController classes, drop TPKeyboardAvoidingTableView.m and TPKeyboardAvoidingTableView.h into your project, and make your UITableView a TPKeyboardAvoidingTableView in the xib. If you're not using a xib with your controller, I know of no easy way to make its UITableView a custom class: The path of least resistance is to create a xib for it.

You can get reference from here.

Hope this helps.