How can I make a UITextField move up when the keyboard is present - on starting to edit?

With the iOS SDK:

I have a UIView with UITextFields that bring up a keyboard. I need it to be able to:

  1. Allow scrolling of the contents of the UIScrollView to see the other text fields once the keyboard is brought up

  2. Automatically "jump" (by scrolling up) or shortening

I know that I need a UIScrollView. I've tried changing the class of my UIView to a UIScrollView but I'm still unable to scroll the textboxes up or down.

Do I need both a UIView and a UIScrollView? Does one go inside the other?

What needs to be implemented in order to automatically scroll to the active text field?

Ideally as much of the setup of the components as possible will be done in Interface Builder. I'd like to only write code for what needs it.

Note: the UIView (or UIScrollView) that I'm working with is brought up by a tabbar (UITabBar), which needs to function as normal.


Edit: I am adding the scroll bar just for when the keyboard comes up. Even though it's not needed, I feel like it provides a better interface because then the user can scroll and change textboxes, for example.

I've got it working where I change the frame size of the UIScrollView when the keyboard goes up and down. I'm simply using:

-(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 + 50);   //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 - 50); //resize
}

However, this doesn't automatically "move up" or center the lower text fields in the visible area, which is what I would really like.

14.07.2009 17:06:07
Check this out. No hassle for you. TPKeyboardAvoiding
Aruna 19.08.2011 19:18:03
It´s documented by Apple, I think it's the best way: developer.apple.com/library/ios/#documentation/StringsTextFonts/…
Maik639 31.07.2013 05:24:25
Use this code.You just need 1 line in appdelegate.m file and it works. github.com/hackiftekhar/IQKeyboardManager
Pradeep Mittal 10.02.2014 10:10:17
The best way I found so far is this open source TPKeyboardAvoiding
Mongi Zaidi 26.03.2014 10:30:30
Another way is to add such contents text fields and all in TableViewController and let tableview handle this.
Vicky Dhas 9.12.2017 11:04:07
30 ОТВЕТОВ
РЕШЕНИЕ
  1. You will only need a ScrollView if the contents you have now do not fit in the iPhone screen. (If you are adding the ScrollView as the superview of the components. just to make the TextField scroll up when keyboard comes up, then it's not needed.)

  2. For showing the textfields without being hidden by the keyboard, the standard way is to move up/down the view having textfields whenever the keyboard is shown.

Here is some sample code:

#define kOFFSET_FOR_KEYBOARD 80.0

-(void)keyboardWillShow {
    // Animate the current view out of the way
    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)keyboardWillHide {
    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];
    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
    if ([sender isEqual:mailTf])
    {
        //move the main view, so that the keyboard does not hide it.
        if  (self.view.frame.origin.y >= 0)
        {
            [self setViewMovedUp:YES];
        }
    }
}

//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view

    CGRect rect = self.view.frame;
    if (movedUp)
    {
        // 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.
        rect.origin.y -= kOFFSET_FOR_KEYBOARD;
        rect.size.height += kOFFSET_FOR_KEYBOARD;
    }
    else
    {
        // revert back to the normal state.
        rect.origin.y += kOFFSET_FOR_KEYBOARD;
        rect.size.height -= kOFFSET_FOR_KEYBOARD;
    }
    self.view.frame = rect;

    [UIView commitAnimations];
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // register for keyboard notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
}
1035
3.03.2018 18:21:16
What does _textField? I copied it into my code, it says _textField is undeclared.
Cocoa Dev 14.12.2010 17:56:27
It's the field that you use to say "when the user is editing here the view should slide up" or something so... However you can remove that if, if you more fields.
patrick 28.01.2011 13:02:08
isn't it batter to call -(void)setViewMovedUp:(BOOL)movedUp in keyBoardWillSHow and KeyBoardWillHide events!!
Abduliam Rehmanius 26.06.2011 04:08:46
Not particularly useful if you're supporting rotations of the main view.
FractalDoctor 2.12.2012 16:00:34
To make this work, I had to comment out the textFieldDidBeginEditing section.
avance 21.09.2016 22:23:29

One thing to consider is whether you ever want to use a UITextField on its own. I haven’t come across any well-designed iPhone apps that actually use UITextFields outside of UITableViewCells.

It will be some extra work, but I recommend you implement all data entry views a table views. Add a UITextView to your UITableViewCells.

48
14.05.2013 05:59:29
One of my apps needs to allow users to add freeform notes- so yes it is sometimes useful to use a UITextField.
Peter Johnson 20.05.2013 22:29:55
I agree with this method. Zero work or code this way. Even if you need a free form note you still can with a table cell
RJH 29.10.2015 15:33:58
UITableView is sadly the only way to go. Keyboard notifications are brittle and have changed overtime. Sample code on Stack Overflow: stackoverflow.com/a/32390936/218152
SwiftArchitect 9.02.2016 22:16:41
This answer is some five years out of date. The only modern solution is something like this ... stackoverflow.com/a/41808338/294884
Fattie 30.11.2017 20:20:44

I'm not sure if moving the view up is the correct approach, I did it in a differente way, resizing the UIScrollView. I explained it in details on a little article

23
24.08.2012 10:25:47
The link to the article is dead.
Teo 20.07.2019 06:51:37

RPDP's code successfully moves the text field out of the way of the keyboard. But when you scroll to the top after using and dismissing the keyboard, the top has been scrolled up out of the view. This is true for the Simulator and the device. To read the content at the top of that view, one has to reload the view.

Isn't his following code supposed to bring the view back down?

else
{
    // revert back to the normal state.
    rect.origin.y += kOFFSET_FOR_KEYBOARD;
    rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
30
5.02.2010 18:27:10

To bring back to original view state, add:

-(void)textFieldDidEndEditing:(UITextField *)sender

{
    //move the main view, so that the keyboard does not hide it.
    if  (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}
22
3.08.2016 06:06:56

Little fix that works for many UITextFields

#pragma mark UIKeyboard handling

#define kMin 150

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
   if (currTextField) {
      [currTextField release];
   }
   currTextField = [sender retain];
   //move the main view, so that the keyboard does not hide it.
   if (self.view.frame.origin.y + currTextField.frame.origin. y >= kMin) {
        [self setViewMovedUp:YES]; 
   }
}



//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
   [UIView beginAnimations:nil context:NULL];
   [UIView setAnimationDuration:0.3]; // if you want to slide up the view

   CGRect rect = self.view.frame;
   if (movedUp)
   {
      // 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.
      rect.origin.y = kMin - currTextField.frame.origin.y ;
   }
   else
   {
      // revert back to the normal state.
      rect.origin.y = 0;
   }
   self.view.frame = rect;

   [UIView commitAnimations];
}


- (void)keyboardWillShow:(NSNotification *)notif
{
   //keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately

   if ([currTextField isFirstResponder] && currTextField.frame.origin.y + self.view.frame.origin.y >= kMin)
   {
      [self setViewMovedUp:YES];
   }
   else if (![currTextField isFirstResponder] && currTextField.frame.origin.y  + self.view.frame.origin.y < kMin)
   {
      [self setViewMovedUp:NO];
   }
}

- (void)keyboardWillHide:(NSNotification *)notif
{
   //keyboard will be shown now. depending for which textfield is active, move up or move down the view appropriately
   if (self.view.frame.origin.y < 0 ) {
      [self setViewMovedUp:NO];
   }

}


- (void)viewWillAppear:(BOOL)animated
{
   // register for keyboard notifications
   [[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]; 
}

- (void)viewWillDisappear:(BOOL)animated
{
   // unregister for keyboard notifications while not visible.
   [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 
}
31
11.02.2010 11:18:14
rect.origin.y=+currTextField.frame.origin.y working fine thank you
u.gen 17.06.2012 11:09:35

Here is the hack solution I came up with for a specific layout. This solution is similar to Matt Gallagher solution in that is scrolls a section into view. I am still new to iPhone development, and am not familiar with how the layouts work. Thus, this hack.

My implementation needed to support scrolling when clicking in a field, and also scrolling when the user selects next on the keyboard.

I had a UIView with a height of 775. The controls are spread out basically in groups of 3 over a large space. I ended up with the following IB layout.

UIView -> UIScrollView -> [UI Components]

Here comes the hack

I set the UIScrollView height to 500 units larger then the actual layout (1250). I then created an array with the absolute positions I need to scroll to, and a simple function to get them based on the IB Tag number.

static NSInteger stepRange[] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 140, 140, 140, 410
};

NSInteger getScrollPos(NSInteger i) {
    if (i < TXT_FIELD_INDEX_MIN || i > TXT_FIELD_INDEX_MAX) {
        return 0 ;
    return stepRange[i] ;
}

Now all you need to do is use the following two lines of code in textFieldDidBeginEditing and textFieldShouldReturn (the latter one if you are creating a next field navigation)

CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
[self.scrollView setContentOffset:point animated:YES] ;

An example.

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    CGPoint point = CGPointMake(0, getScrollPos(textField.tag)) ;
    [self.scrollView setContentOffset:point animated:YES] ;
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField {

    NSInteger nextTag = textField.tag + 1;
    UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];

    if (nextResponder) {
        [nextResponder becomeFirstResponder];
        CGPoint point = CGPointMake(0, getScrollPos(nextTag)) ;
        [self.scrollView setContentOffset:point animated:YES] ;
    }
    else{
        [textField resignFirstResponder];
    }

    return YES ;
}

This method does not 'scroll back' as other methods do. This was not a requirement. Again this was for a fairly 'tall' UIView, and I did not have days to learn the internal layout engines.

12
28.03.2010 22:17:38

I was also having a lot of issue with a UIScrollView composing of multiple UITextFields, of which, one or more of them would get obscured by the keyboard when they are being edited.

Here are some things to consider if your UIScrollView is not properly scrolling.

1) Ensure that your contentSize is greater than the UIScrollView frame size. The way to understand UIScrollViews is that the UIScrollView is like a viewing window on the content defined in the contentSize. So when in order for the UIScrollview to scroll anywhere, the contentSize must be greater than the UIScrollView. Else, there is no scrolling required as everything defined in the contentSize is already visible. BTW, default contentSize = CGSizeZero.

2) Now that you understand that the UIScrollView is really a window into your "content", the way to ensure that the keyboard is not obscuring your UIScrollView's viewing "window" would be to resize the UIScrollView so that when the keyboard is present, you have the UIScrollView window sized to just the original UIScrollView frame.size.height minus the height of the keyboard. This will ensure that your window is only that small viewable area.

3) Here's the catch: When I first implemented this I figured I would have to get the CGRect of the edited textfield and call UIScrollView's scrollRecToVisible method. I implemented the UITextFieldDelegate method textFieldDidBeginEditing with the call to the scrollRecToVisible method. This actually worked with a strange side effect that the scrolling would snap the UITextField into position. For the longest time I couldn't figure out what it was. Then I commented out the textFieldDidBeginEditing Delegate method and it all work!!(???). As it turned out, I believe the UIScrollView actually implicitly brings the currently edited UITextField into the viewable window implicitly. My implementation of the UITextFieldDelegate method and subsequent call to the scrollRecToVisible was redundant and was the cause of the strange side effect.

So here are the steps to properly scroll your UITextField in a UIScrollView into place when the keyboard appears.

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.

- (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)keyboardWillHide:(NSNotification *)n
{
    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] 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];
    [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
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] 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];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];
    keyboardIsShown = YES;
}
  1. Register for the keyboard notifications at viewDidLoad
  2. Unregister for the keyboard nofitications at viewDidUnload
  3. Ensure that the contentSize is set and greater than your UIScrollView at viewDidLoad
  4. Shrink the UIScrollView when the keyboard is present
  5. Revert back the UIScrollView when the keyboard goes away.
  6. Use an ivar to detect if the keyboard is already shown on the screen since the keyboard notifications are sent each time a UITextField is tabbed even if the keyboard is already present to avoid shrinking the UIScrollView when it's already shrunk

One thing to note is that the UIKeyboardWillShowNotification will fire even when the keyboard is already on the screen when you tab on another UITextField. I took care of this by using an ivar to avoid resizing the UIScrollView when the keyboard is already on the screen. Inadvertently resizing the UIScrollView when the keyboard is already there would be disastrous!

Hope this code saves some of you a lot of headache.

445
31.10.2017 12:58:42
Great, but two problems: 1. UIKeyboardBoundsUserInfoKey is deprecated. 2. keyboardSize is in "screen coordinates", so your viewFrame calculations will fail if the frame is rotated or scaled.
Martin Wickman 20.04.2011 21:26:32
@Martin Wickman - Use CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; instead of the deprecated UIKeyboardBoundsUserInfoKey
sottenad 30.07.2011 20:51:54
HI, I did the same, but the text view only moves up when user starts typing? Is it the expected behavior or I am missing something?
user517491 19.04.2012 13:07:08
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size should be [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size . Great solution though!
j7nn7k 24.05.2012 08:09:54
I like your solution but I think I can make it even simpler: don't bother with the Notification Observer stuff; instead call the right animation routines inside the appropriate delegate methods -- for UITextView they're textViewDidBeginEditing and textViewDidEndEditing.
AlexChaffee 12.02.2013 23:51:39

This document details a solution to this problem. Look at the source code under 'Moving Content That Is Located Under the Keyboard'. It's pretty straightforward.

EDIT: Noticed there's a wee glitch in the example. You will probably want to listen for UIKeyboardWillHideNotification instead of UIKeyboardDidHideNotification. Otherwise the scroll view behind of the keyboard will be clipped for the duration of the keyboard closing animation.

47
14.05.2013 05:58:49

@user271753

To get your view back to original add:

-(BOOL)textFieldShouldReturn:(UITextField *)textField{
   [textField resignFirstResponder];
   [self setViewMovedUp:NO];
   return YES;
}
18
2.05.2016 12:06:19

Shiun said "As it turned out, I believe the UIScrollView actually implicitly brings the currently edited UITextField into the viewable window implicitly" This seems to be true for iOS 3.1.3, but not 3.2, 4.0, or 4.1. I had to add an explicit scrollRectToVisible in order to make the UITextField visible on iOS >= 3.2.

62
17.12.2017 10:45:04
It's not the UIScrollView which scrolls implicitly the edited UITextField into view, its the UITextField which calls a private [UITextField scrollTextFieldToVisibleIfNecessary] method which in turn calls [UIScrollView scrollRectToVisible] when [UITextField becomeFirstResponder] is called. See github.com/leopatras/ios_textfields_on_scrollview. If constraints and view controllers are setup properly there is actually no need to call scrollRectToVisible explicitly (at least since IOS 11).
Leo 29.12.2019 21:11:45

It's actually best just to use Apple's implementation, as provided in the docs. However, the code they provide is faulty. Replace the portion found in keyboardWasShown: just below the comments to the following:

NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);

CGPoint origin =  activeRect.origin;
origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin)) {
    CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
    [backScrollView setContentOffset:scrollPoint animated:YES];
}

The problems with Apple's code are these: (1) They always calculate if the point is within the view's frame, but it's a ScrollView, so it may already have scrolled and you need to account for that offset:

origin.y -= scrollView.contentOffset.y

(2) They shift the contentOffset by the height of the keyboard, but we want the opposite (we want to shift the contentOffset by the height that is visible on the screen, not what isn't):

activeField.frame.origin.y-(aRect.size.height)
270
29.12.2019 11:38:05
In situations where the scroll view is not filling the screen, aRect should be set to the scroll view's frame
mblackwell8 9.05.2013 04:48:36
Shouldn't you want the CGPoint origin = activeField.frame.origin + activeField.frame.size.height ?, because you want the whole textfield to be displayed and if it happens to have just some pixels visible then code won't enter the condition.
htafoya 15.04.2014 17:16:48
This solution doesn't work in Landscape orientation — the text field flies off the top of the view port. iPad with iOS 7.1.
Andrew 27.04.2014 09:47:12
For better iOS 8 support, I'd suggest using UIKeyboardFrameEndUserInfoKey instead of UIKeyboardFrameBeginUserInfoKey when getting the keyboard size, as this will pick up things such as custom keyboard changes and toggling predictive text on/off.
Endareth 13.11.2014 02:06:09
@Egor: Your fix makes it work way better - but the last line must be inverse: self.scrollView.contentOffset = self.currentSVoffset;
Morten Holmgaard 23.01.2015 07:32:44

When UITextField is in a UITableViewCell scrolling should be setup automatically.

If it is not it is probably because of incorrect code/setup of the tableview.

For example when i reloaded my long table with one UITextField at the bottom as follows,

-(void) viewWillAppear:(BOOL)animated
{
   [self.tableview reloadData];
}

then my textfield at the bottom was obscured by the keyboard which appeared when I clicked inside the textfield.

To fix this I had to do this -

-(void) viewWillAppear:(BOOL)animated
{
    //add the following line to fix issue
    [super viewWillAppear:animated];
    [self.tableview reloadData];
}
10
3.08.2016 06:07:49
I'm confused what this code is for? When the keyboard is shown, viewWillAppear is not called. And reloadData doesn't make obscured rows become visible.
Adam Johns 8.08.2014 21:03:00

I've put together a universal, drop-in UIScrollView, UITableView and even UICollectionView subclass that takes care of moving all text fields within it out of the way of the keyboard.

When the keyboard is about to appear, the subclass will find the subview that's about to be edited, and adjust its frame and content offset to make sure that view is visible, with an animation to match the keyboard pop-up. When the keyboard disappears, it restores its prior size.

It should work with basically any setup, either a UITableView-based interface, or one consisting of views placed manually.

Here' tis: solution for moving text fields out of the way of the keyboard

101
16.12.2014 07:06:04
This is it! This is the best, most efficient, and perfect solution! It also handles rotations properly for scroll views. If rotating be sure to autoresize vertically but do not anchor at the bottom. I added a UITextView to the scroll view in my case. Thanks bunches!
Christopher 18.06.2012 01:36:23
Very nice work! Sure, I'm being lazy using your solution instead of the DIY one, but my boss is happier, so yeah! Even if someone does want to do themselves, I like your subclass approach, instead of adding code to each controller. I was shocked iOS didn't do this by default like Android did -- then again, I'm finding a lot of things lacking in iOS and MacOS :(
eselk 11.10.2012 18:34:49
Does weird things like my scrollview all fits in the screen, so it can't be scrolled. After opening and closing the keyboard, the content is now larger (looks like something invisible was added and not removed at the bottom of the page), and can be scrolled.
Almo 23.11.2014 01:48:55

In textFieldDidBeginEditting and in textFieldDidEndEditing call the function [self animateTextField:textField up:YES] like so:

-(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 = -130; // 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];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

I hope this code will help you.

In Swift 2

func animateTextField(textField: UITextField, up: Bool) 
{
     let movementDistance:CGFloat = -130
     let movementDuration: Double = 0.3

     var movement:CGFloat = 0
     if up 
     {
         movement = movementDistance
     }
     else 
     {
         movement = -movementDistance
     }
     UIView.beginAnimations("animateTextField", context: nil)
     UIView.setAnimationBeginsFromCurrentState(true)
     UIView.setAnimationDuration(movementDuration)
     self.view.frame = CGRectOffset(self.view.frame, 0, movement)
     UIView.commitAnimations()
}


func textFieldDidBeginEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:true)
}

func textFieldDidEndEditing(textField: UITextField) 
{
    self.animateTextField(textField, up:false)
}

SWIFT 3

 func animateTextField(textField: UITextField, up: Bool)
    {
        let movementDistance:CGFloat = -130
        let movementDuration: Double = 0.3

        var movement:CGFloat = 0
        if up
        {
            movement = movementDistance
        }
        else
        {
            movement = -movementDistance
        }
        UIView.beginAnimations("animateTextField", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration)
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }


    func textFieldDidBeginEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:true)
    }

    func textFieldDidEndEditing(textField: UITextField)
    {
        self.animateTextField(textField: textField, up:false)
    }
244
4.10.2016 15:21:45
why not use [UIView animateWithDuration: animations:^{ }]; ?
Andre Cytryn 8.08.2012 22:20:48
this works good, though const int movementDistance = -130; // tweak as needed needs to be changed to more flexible
Hammer 10.10.2014 03:57:22
Incredibly simple on small implementations. No mucking around with ScrollViews and Ambiguous auto-layout issues.
James Perih 9.05.2015 02:13:15
Erm...you don´t use the textField parameter at all. Why then have it as a function parameter? Additionally, you could use the ternary operator also in Swift. Makes the code less talky.
stk 23.10.2016 15:16:31
If the background color of the View is something other than black, make sure you set the color of the Window to match your view so the user doesn't see behind it. i.e. self.window.backgroundColor = [UIColor whiteColor];
bvmobileapps 21.03.2017 22:23:37

It doesn't require a scroll view to be able to move the view frame. You can change the frame of a viewcontroller's view so that the entire view moves up just enough to put the firstresponder text field above the keyboard. When I ran into this problem I created a subclass of UIViewController that does this. It observes for the keyboard will appear notification and finds the first responder subview and (if needed) it animates the main view upward just enough so that the first responder is above the keyboard. When the keyboard hides, it animates the view back where it was.

To use this subclass make your custom view controller a subclass of GMKeyboardVC and it inherits this feature (just be sure if you implement viewWillAppear and viewWillDisappear they must call super). The class is on github.

16
14.05.2013 06:01:01
What license? Some of your files there have an open source license and some don't.
jaime 13.09.2013 21:57:17
Warning: this code is not friendly with ARC projects.
Almo 23.11.2014 02:05:56
You just add the build option to specify that those are non-ARC files or welcome to convert it to ARC and submit a pull request.
progrmr 23.11.2014 16:12:28

Been searching for a good tutorial for beginners on the subject, found the best tutorial here.

In the MIScrollView.h example at the bottom of the tutorial be sure to put a space at

@property (nonatomic, retain) id backgroundTapDelegate;

as you see.

10
2.01.2012 20:42:17
Hi savagenoob, thanks for the link provided and welcome to stackoverflow. Please try and provide as much info as you can when answering (future) questions - simple links are a bit brittle. That said, if the answer is a link to a good tutorial that might be overlooked.
Maarten Bodewes 1.01.2012 23:56:53

You need to add scrollview programmatically with specific frame size. You have to add UIScrollViewDelegate in .h file. You have to enable scrollview for that you need to write following in viewDidLoad().

scrollview.scrollEnabled=YES;
scrollview.delegate=self;

scrollview.frame = CGRectMake(x,y,width,height);
//---set the content size of the scroll view--- 

[scrollview setContentSize:CGSizeMake(height,width)];

This way, you can add your x, y, width and height values.

7
22.11.2019 00:57:54

A much, much more elegant solution is to use a UIView subclass (though this isn't always appropriate) and recalculate all your subviews on a parent's frame change (and be smart: only recalculate them if the new frame size has changed, i.e. use CGRectEqualToRect to compare the new frame when you override setFrame and BEFORE you call [super setFrame:frame_]). The only catch to this is that the UIViewController you intend to use should probably listen to keyboard events (or, you could do it in the UIView itself, for handy encapsulation). But only the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification. This is just so it will look smooth (if you wait for CG to call it, you will get a moment of choppiness).

This has the advantage of building a UIView subclass that does the right thing, anyway.

The naive implementation would be to override drawRect: (don't), a better one would be to just use layoutSubviews (and then in the UIViewController, or whatnot you can call [view setNeedsLayout] in a SINGLE method that is called for either show or hide).

This solution gets away from hardcoding a keyboard offset (which will change if they are not in split, etc) and also means that your view could be a subview of many other views and still respond properly.

Don't hardcode something like that unless there is no other solution. The OS gives you enough info, if you've done things right, that you just need to redraw intelligently (based on your new frame size). This is much cleaner and the way you should do things. (There may be an even better approach, though.)

Cheers.

5
30.01.2012 17:07:13

Try this:

-(void)textFieldDidBeginEditing:(UITextField *)sender
{
    if ([sender isEqual:self.m_Sp_Contact])
    {
        [self.m_Scroller setContentOffset:CGPointMake(0, 105)animated:YES];          
    }
}
7
20.07.2012 07:40:02

Please follow these steps ,it might be helpful. Put one view then put your textfield on that view and detect the event by delegate when your keyboard is coming up,at that time instant animate the view up(You can assign some position for that view also),then your view would be going up to that position.Do the same thing for animating the view down.

Thanks

1
25.07.2012 08:59:13

As per the docs, as of iOS 3.0, the UITableViewController class automatically resizes and repositions its table view when there is in-line editing of text fields. I think it's not sufficient to put the text field inside a UITableViewCell as some have indicated.

From the docs:

A table view controller supports inline editing of table view rows; if, for example, rows have embedded text fields in editing mode, it scrolls the row being edited above the virtual keyboard that is displayed.

12
4.10.2012 02:57:16
I found the same comment. Yes, it is true. The strange thing is, that it is working in one UITabelViewController and in a second one not. But I could not find any differences in my implementation.
Morpheus78 13.12.2016 00:50:05

There so many solutions, but I've spend some hours before it start works. So, I put this code here (just paste to the project, any modifications needn't):

@interface RegistrationViewController : UIViewController <UITextFieldDelegate>{
    UITextField* activeField;
    UIScrollView *scrollView;
}
@end

- (void)viewDidLoad
{
    [super viewDidLoad];

    scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];

    //scrool view must be under main view - swap it
    UIView* natView = self.view;
    [self setView:scrollView];
    [self.view addSubview:natView];

    CGSize scrollViewContentSize = self.view.frame.size;
    [scrollView setContentSize:scrollViewContentSize];

    [self registerForKeyboardNotifications];
}

- (void)viewDidUnload {
    activeField = nil;
    scrollView = nil;
    [self unregisterForKeyboardNotifications];
    [super viewDidUnload];
}

- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShown:)
                                                 name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];

}

-(void)unregisterForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillShowNotification
                                                  object:nil];
    // unregister for keyboard notifications while not visible.
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIKeyboardWillHideNotification
                                                  object:nil];
}

- (void)keyboardWillShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect frame = self.view.frame;
    frame.size.height -= kbSize.height;
    CGPoint fOrigin = activeField.frame.origin;
    fOrigin.y -= scrollView.contentOffset.y;
    fOrigin.y += activeField.frame.size.height;
    if (!CGRectContainsPoint(frame, fOrigin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y + activeField.frame.size.height - frame.size.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }
}

- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
     [scrollView setContentOffset:CGPointZero animated:YES];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    activeField = nil;
}

-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

P.S: I hope the code help somebody make desired effect quickly. (Xcode 4.5)

19
12.10.2012 09:14:14
Hi Hotjard, i am getting EXE_BAD_ACCESS in the [self.view addSubview:natView];
Bala 8.10.2014 11:16:01

Lots of answers here, but this works and is much shorter than most:

- (void)textFieldDidBeginEditing:(UITextField *)sender
{
    UIScrollView *scrollView = (UIScrollView *)self.view; // assuming this method is pasted into the UIScrollView's controller
    const double dontHardcodeTheKeyboardHeight = 162;
    double textY = [sender convertPoint:CGPointMake(0, 0) toView:scrollView].y;
    if (textY - scrollView.contentOffset.y + sender.frame.size.height > self.view.frame.size.height - dontHardcodeTheKeyboardHeight)
        [scrollView setContentOffset:CGPointMake(0.0, textY - 10) animated:YES];
}
2
12.10.2012 23:47:19

Just using TextFields:

1a) Using Interface Builder: Select All TextFields => Edit => Embed In => ScrollView

1b) Manually embed TextFields in UIScrollView called scrollView

2) Set UITextFieldDelegate

3) Set each textField.delegate = self; (or make connections in Interface Builder)

4) Copy / Paste:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
    [scrollView setContentOffset:scrollPoint animated:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [scrollView setContentOffset:CGPointZero animated:YES];
}
134
1.12.2012 14:53:19
But it also moves up the view when textField is already visible.
TheTiger 5.05.2014 07:03:32
Need to change CGPointMake(0, textField.frame.origin.y); to CGPointMake(0, textField.frame.origin.y + scrollView.contentInset.top);
Andrew 11.01.2015 14:24:21
@Egor Even after your comment it doesn't work. Like "TheTiger" mentioned it moves up the view even after textfield is visible.
rak appdev 3.04.2017 18:32:33
Change for XCode 10: "Select All TextFields => Editor => Embed In => Scroll View"
tibalt 7.05.2019 16:57:17

You can do by using textfield delegate methods also. Check below code. It's working for me when placed textfield on scroll view.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
     if(textField == answer)
    {   
         CGPoint cPoint = textField.frame.origin;
         [scrollView setContentOffset:CGPointMake(0, cPoint.y - 100) animated:YES];
    }
}

Note: You have to change cPoint.y - 100 value according to your view.

4
2.05.2016 12:08:00

Here is a free library for keyboard handling Keyboard-Handling-in-iPhone-Applications. You need write just one line of code:

[AutoScroller addAutoScrollTo:scrollView];

This is awesome to handle keyboard in forms

6
14.06.2013 10:51:53
Register to download? ..no thanks. Please host on github or similar.
quantumpotato 14.01.2013 05:08:08
not bad, but I have a problem with this library. It's a pitty that code is not on github. But anyway, thanks.
George 23.05.2013 13:14:14

There are already a lot of answers, but still none of the solutions above had all the fancy positioning stuff required for a "perfect" bug-free, backwards compatible and flicker-free animation. (bug when animating frame/bounds and contentOffset together, different interface orientations, iPad split keyboard, ...)
Let me share my solution:
(assuming you have set up UIKeyboardWill(Show|Hide)Notification)

// Called when UIKeyboardWillShowNotification is sent
- (void)keyboardWillShow:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = [notification userInfo];

    CGRect keyboardFrameInWindow;
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindow];

    // the keyboard frame is specified in window-level coordinates. this calculates the frame as if it were a subview of our view, making it a sibling of the scroll view
    CGRect keyboardFrameInView = [self.view convertRect:keyboardFrameInWindow fromView:nil];

    CGRect scrollViewKeyboardIntersection = CGRectIntersection(_scrollView.frame, keyboardFrameInView);
    UIEdgeInsets newContentInsets = UIEdgeInsetsMake(0, 0, scrollViewKeyboardIntersection.size.height, 0);

    // this is an old animation method, but the only one that retains compaitiblity between parameters (duration, curve) and the values contained in the userInfo-Dictionary.
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    _scrollView.contentInset = newContentInsets;
    _scrollView.scrollIndicatorInsets = newContentInsets;

    /*
     * Depending on visual layout, _focusedControl should either be the input field (UITextField,..) or another element
     * that should be visible, e.g. a purchase button below an amount text field
     * it makes sense to set _focusedControl in delegates like -textFieldShouldBeginEditing: if you have multiple input fields
     */
    if (_focusedControl) {
        CGRect controlFrameInScrollView = [_scrollView convertRect:_focusedControl.bounds fromView:_focusedControl]; // if the control is a deep in the hierarchy below the scroll view, this will calculate the frame as if it were a direct subview
        controlFrameInScrollView = CGRectInset(controlFrameInScrollView, 0, -10); // replace 10 with any nice visual offset between control and keyboard or control and top of the scroll view.

        CGFloat controlVisualOffsetToTopOfScrollview = controlFrameInScrollView.origin.y - _scrollView.contentOffset.y;
        CGFloat controlVisualBottom = controlVisualOffsetToTopOfScrollview + controlFrameInScrollView.size.height;

        // this is the visible part of the scroll view that is not hidden by the keyboard
        CGFloat scrollViewVisibleHeight = _scrollView.frame.size.height - scrollViewKeyboardIntersection.size.height;

        if (controlVisualBottom > scrollViewVisibleHeight) { // check if the keyboard will hide the control in question
            // scroll up until the control is in place
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y += (controlVisualBottom - scrollViewVisibleHeight);

            // make sure we don't set an impossible offset caused by the "nice visual offset"
            // if a control is at the bottom of the scroll view, it will end up just above the keyboard to eliminate scrolling inconsistencies
            newContentOffset.y = MIN(newContentOffset.y, _scrollView.contentSize.height - scrollViewVisibleHeight);

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        } else if (controlFrameInScrollView.origin.y < _scrollView.contentOffset.y) {
            // if the control is not fully visible, make it so (useful if the user taps on a partially visible input field
            CGPoint newContentOffset = _scrollView.contentOffset;
            newContentOffset.y = controlFrameInScrollView.origin.y;

            [_scrollView setContentOffset:newContentOffset animated:NO]; // animated:NO because we have created our own animation context around this code
        }
    }

    [UIView commitAnimations];
}


// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillHide:(NSNotification*)notification
{
    // if we have no view or are not visible in any window, we don't care
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }

    NSDictionary *userInfo = notification.userInfo;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];

    // undo all that keyboardWillShow-magic
    // the scroll view will adjust its contentOffset apropriately
    _scrollView.contentInset = UIEdgeInsetsZero;
    _scrollView.scrollIndicatorInsets = UIEdgeInsetsZero;

    [UIView commitAnimations];
}
64
24.06.2017 09:40:19
Great improvements of @Shiun answer. But after keyboard is gone, the view do not back in the 1st position. It's still a great work :)
Lucien 6.06.2013 12:40:11
Thanks, this is the best solution for me in 2017. Note that you don't need to track the focusedControl yourself, you can determine that with UIApplication.shared.sendAction(...). Here's the Swift 3 version of your answer (minus willHide portion), with the sendAction implemented: gist.github.com/xaphod/7aab1302004f6e933593a11ad8f5a72d
xaphod 2.06.2017 20:41:06
@xaphod in my case I needed to focus more controls - e.g. a button below an input field. but yeah that code is now 4 years old and may benefit from improvements.
Martin Ullrich 25.06.2017 16:33:43
This is probably the proper solution. Keyboard notification carries animation data, the text field delegations do not know about animation duration, it would just be a guess work.
X.Y. 26.01.2019 17:42:09

Please follow these steps.

1) Declare following variable in .h file.

  {      
         CGFloat animatedDistance;
  }

2) Declare following constants in .m file.

  static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
  static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
  static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
  static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
  static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;

3) Use UITextField delegate to move up/down keyboard.

  -(void) textFieldDidBeginEditing:(UITextField *)textField
  { 
         if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
         {
               CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
               CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];

               CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
               CGFloat numerator =
    midline - viewRect.origin.y
    - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
               CGFloat denominator =
    (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
    * viewRect.size.height;
               CGFloat heightFraction = numerator / denominator;

               if (heightFraction < 0.0)
               {
                     heightFraction = 0.0;
               }
               else if (heightFraction > 1.0)
               {
                     heightFraction = 1.0;
               }

               UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
               if (orientation == UIInterfaceOrientationPortrait)
               {
                     animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
               }
               else
               {
                     animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
               }

               CGRect viewFrame = self.view.frame;
               viewFrame.origin.y -= animatedDistance;

               [UIView beginAnimations:nil context:NULL];
               [UIView setAnimationBeginsFromCurrentState:YES];
               [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

               [self.view setFrame:viewFrame];

               [UIView commitAnimations];
       }
  }

  -(void) textFieldDidEndEditing:(UITextField *)textField
  {
       if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
       {
             CGRect viewFrame = self.view.frame;
             viewFrame.origin.y += animatedDistance;

             [UIView beginAnimations:nil context:NULL];
             [UIView setAnimationBeginsFromCurrentState:YES];
             [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

             [self.view setFrame:viewFrame];

             [UIView commitAnimations];
       }
 }
3
2.04.2013 06:47:31
This answer was directly copied from cocoawithlove.com/2008/10/…
koen 9.10.2013 17:48:36

For Universal Solution, Here was my approach for implementing IQKeyboardManager.

enter image description here

Step1:- I Added global notifications of UITextField, UITextView, and UIKeyboard in a singleton class. I call it IQKeyboardManager.

Step2:- If found UIKeyboardWillShowNotification, UITextFieldTextDidBeginEditingNotification or UITextViewTextDidBeginEditingNotification notifications, I try to get topMostViewController instance from the UIWindow.rootViewController hierarchy. In order to properly uncover UITextField/UITextView on it, topMostViewController.view's frame needs to be adjusted.

Step3:- I calculated expected move distance of topMostViewController.view with respect to first responded UITextField/UITextView.

Step4:- I moved topMostViewController.view.frame up/down according to the expected move distance.

Step5:- If found UIKeyboardWillHideNotification, UITextFieldTextDidEndEditingNotification or UITextViewTextDidEndEditingNotification notification, I again try to get topMostViewController instance from the UIWindow.rootViewController hierarchy.

Step6:- I calculated disturbed distance of topMostViewController.view which needs to be restored to it's original position.

Step7:- I restored topMostViewController.view.frame down according to the disturbed distance.

Step8:- I instantiated singleton IQKeyboardManager class instance on app load, so every UITextField/UITextView in the app will adjust automatically according to the expected move distance.

That's all IQKeyboardManager do for you with NO LINE OF CODE really!! only need to drag and drop related source file to project. IQKeyboardManager also support Device Orientation, Automatic UIToolbar Management, KeybkeyboardDistanceFromTextField and much more than you think.

116
18.12.2014 16:24:01
Add IQKeyBoardManagerSwift directory to my project and don't work. Can't enable cuz its not recognize in AppDelegate...
user3722523 5.11.2015 17:45:43
this feels like phishing the actual solution is not shown but instead we see a commercial to this guys GitHub account.
Brian 5.01.2018 23:29:07