With the iOS SDK:
I have a UIView
with UITextField
s that bring up a keyboard. I need it to be able to:
Allow scrolling of the contents of the
UIScrollView
to see the other text fields once the keyboard is brought upAutomatically "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.
For Universal Solution, Here was my approach for implementing IQKeyboardManager.
Step1:- I Added global notifications of
UITextField
,UITextView
, andUIKeyboard
in a singleton class. I call it IQKeyboardManager.Step2:- If found
UIKeyboardWillShowNotification
,UITextFieldTextDidBeginEditingNotification
orUITextViewTextDidBeginEditingNotification
notifications, I try to gettopMostViewController
instance from theUIWindow.rootViewController
hierarchy. In order to properly uncoverUITextField
/UITextView
on it,topMostViewController.view
's frame needs to be adjusted.Step3:- I calculated expected move distance of
topMostViewController.view
with respect to first respondedUITextField
/UITextView
.Step4:- I moved
topMostViewController.view.frame
up/down according to the expected move distance.Step5:- If found
UIKeyboardWillHideNotification
,UITextFieldTextDidEndEditingNotification
orUITextViewTextDidEndEditingNotification
notification, I again try to gettopMostViewController
instance from theUIWindow.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.
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
)This is the solution using Swift.
@user271753
To get your view back to original add:
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: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:(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):In
textFieldDidBeginEditting
and intextFieldDidEndEditing
call the function[self animateTextField:textField up:YES]
like so:I hope this code will help you.
In Swift 2
SWIFT 3