ios - कुंजीपटल मौजूद होने पर मैं UITextField को कैसे बढ़ा सकता हूं?




objective-c uikeyboard (20)

स्विफ्ट प्रोग्रामर के लिए:

यह आपके लिए सब कुछ करेगा, बस इन्हें अपने व्यू कंट्रोलर क्लास में डालें और UITextFieldDelegate को अपने व्यू कंट्रोलर में कार्यान्वित करें और टेक्स्टफिल्ड के प्रतिनिधि को self सेट करें

textField.delegate = self // Setting delegate of your UITextField to self

प्रतिनिधि कॉलबैक विधियों को लागू करें:

func textFieldDidBeginEditing(textField: UITextField) {
    animateViewMoving(true, moveValue: 100)
}

func textFieldDidEndEditing(textField: UITextField) {
    animateViewMoving(false, moveValue: 100)
}

// Lifting the view up
func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:NSTimeInterval = 0.3
    let movement:CGFloat = ( up ? -moveValue : moveValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration )
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}

आईओएस एसडीके के साथ:

मेरे पास UITextField s के साथ UIView जो एक कीबोर्ड लाता है। मुझे यह करने में सक्षम होना चाहिए:

  1. कुंजीपटल लाए जाने के बाद अन्य टेक्स्ट फ़ील्ड्स देखने के लिए UIScrollView की सामग्री को UIScrollView करने दें

  2. स्वचालित रूप से "कूदें" (स्क्रॉल करके) या छोटा करना

मुझे पता है कि मुझे UIScrollView आवश्यकता है। मैंने अपने UIView की कक्षा को UIScrollView बदलने का प्रयास किया है, लेकिन मैं अभी भी टेक्स्टबॉक्स को ऊपर या नीचे स्क्रॉल करने में असमर्थ हूं।

क्या मुझे UIView और UIScrollView दोनों की आवश्यकता है? क्या कोई दूसरे के अंदर जाता है?

सक्रिय टेक्स्ट फ़ील्ड को स्वचालित रूप से स्क्रॉल करने के लिए क्या लागू करने की आवश्यकता है?

आदर्श रूप से जितना संभव हो सके घटकों के सेटअप को इंटरफ़ेस बिल्डर में किया जाएगा। मैं केवल उस कोड के लिए कोड लिखना चाहता हूं जिसके लिए इसकी आवश्यकता है।

नोट: UIView (या UIScrollView ) जिसे मैं साथ काम कर रहा हूं उसे एक टैबबार ( UITabBar ) द्वारा लाया गया है, जिसे सामान्य के रूप में कार्य करने की आवश्यकता है।

संपादित करें: जब कीबोर्ड आता है तो मैं स्क्रॉल बार जोड़ रहा हूं। भले ही इसकी आवश्यकता नहीं है, मुझे लगता है कि यह एक बेहतर इंटरफ़ेस प्रदान करता है क्योंकि उपयोगकर्ता उदाहरण के लिए टेक्स्टबॉक्स को स्क्रॉल और बदल सकता है।

जब मैं कीबोर्ड ऊपर और नीचे जाता हूं तो मुझे यह काम मिल गया है जहां मैं UIScrollView के फ्रेम आकार को बदलता हूं। मैं बस उपयोग कर रहा हूँ:

-(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
}

हालांकि, यह स्वचालित रूप से दृश्य क्षेत्र में निचले पाठ फ़ील्ड को "ऊपर" या केंद्र में नहीं ले जाता है, जो मुझे वास्तव में पसंद आएगा।


Here I found the simplest solution to handle keypad.

You need to just copy-paste below sample code and change your textfield or any view which you want to move up.

Step-1

Just copy-paste below two method in your controller

- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];
}

- (void)deregisterFromKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

Step-2

register & deregister Keypad Notifications in viewWillAppear and viewWillDisappear methods respectively.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self registerForKeyboardNotifications];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self deregisterFromKeyboardNotifications];
    [super viewWillDisappear:animated];
}

Step-3

Here comes the soul part, Just replace your textfield, and change height how much you want to move upside.

- (void)keyboardWasShown:(NSNotification *)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize currentKeyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    //you need replace your textfield instance here
    CGPoint textFieldOrigin = self.tokenForPlaceField.frame.origin;
    CGFloat textFieldHeight = self.tokenForPlaceField.frame.size.height;

    CGRect visibleRect = self.view.frame;
    visibleRect.size.height -= currentKeyboardSize.height;

    if (!CGRectContainsPoint(visibleRect, textFieldOrigin))
    {
        //you can add yor desired height how much you want move keypad up, by replacing "textFieldHeight" below

        CGPoint scrollPoint = CGPointMake(0.0, textFieldOrigin.y - visibleRect.size.height  + textFieldHeight); //replace textFieldHeight to currentKeyboardSize.height, if you want to move up with more height
        [self.scrollView setContentOffset:scrollPoint animated:YES];
    }
}

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

Reference : well, Please appreciate this guy , who shared this beautiful code snip, clean solution.

Hope this would be surly helpful someone out there.


इसे इस्तेमाल करे:

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

पहले से ही बहुत सारे उत्तर हैं, लेकिन अभी भी उपरोक्त समाधानों में से कोई भी "फैंसी" बग-फ्री, पिछड़ा संगत और झिलमिलाहट मुक्त एनीमेशन के लिए आवश्यक सभी फैंसी पोजीशनिंग सामग्री नहीं है। (फ्रेम / सीमाओं और सामग्री को एनिमेट करते समय बग एक साथ ऑफ़सेट करें, विभिन्न इंटरफ़ेस ओरिएंटेशन, आईपैड स्प्लिट कीबोर्ड, ...)
मुझे अपना समाधान साझा करने दें:
(मान UIKeyboardWill(Show|Hide)Notification कि आपने 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];
}

मैंने एक सार्वभौमिक, ड्रॉप-इन UIScrollView , UITableView और यहां तक ​​कि UICollectionView subclass को एक साथ रखा है जो कुंजीपटल के रास्ते से सभी टेक्स्ट फ़ील्ड को स्थानांतरित करने का ख्याल रखता है।

जब कीबोर्ड दिखाई देने वाला है, तो सबक्लास को उस सबव्यूव को मिलेगा जो संपादित होने वाला है, और यह सुनिश्चित करने के लिए कि दृश्य दृश्यमान है, कीबोर्ड एनीमेशन से मेल खाने के लिए एनीमेशन के साथ, इसके फ्रेम और सामग्री ऑफ़सेट को समायोजित करें। जब कीबोर्ड गायब हो जाता है, तो यह इसके पूर्व आकार को पुनर्स्थापित करता है।

इसे मूल रूप से किसी भी सेटअप के साथ काम करना चाहिए, या तो UITableView व्यू-आधारित इंटरफेस, या मैन्युअल रूप से रखे गए विचारों वाला एक।

यहां 'tis: कुंजीपटल के रास्ते से टेक्स्ट फ़ील्ड को स्थानांतरित करने के लिए समाधान


developer.apple.com/library/ios/#documentation/StringsTextFonts/… 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.


textFieldDidBeginEditting [self animateTextField:textField up:YES] में और textFieldDidEndEditing फ़ंक्शन को कॉल करें [self animateTextField:textField up:YES] जैसे:

-(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];
}

मुझे आशा है कि यह कोड आपकी मदद करेगा।

स्विफ्ट 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)
}

स्विफ्ट 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)
    }

Easiest solution found

- (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 = 80; // 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];
}

बस टेक्स्टफिल्ड्स का उपयोग करना:

1 ए) Interface Builder का उपयोग करना: सभी TextFields => संपादित करें => एम्बेड करें => स्क्रॉलव्यू चुनें

1 बी) UIScrollView में मैन्युअल रूप से टेक्स्टफिल्ड्स एम्बेड करें scrollView कहा जाता है

2) UITextFieldDelegate सेट करें

3) प्रत्येक textField.delegate = self; सेट करें textField.delegate = self; (या Interface Builder में कनेक्शन बनाएं)

4) कॉपी / पेस्ट करें:

- (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];
}

सार्वभौमिक समाधान के लिए , IQKeyboardManager को लागू करने के लिए मेरा दृष्टिकोण यहां था।

चरण 1: - मैंने एक सिंगलटन कक्षा में UITextField , UITextView , और UIKeyboard की वैश्विक सूचनाएं जोड़ UIKeyboard । मैं इसे IQKeyboardManager कहते हैं।

चरण 2: - यदि UIKeyboardWillShowNotification , UITextFieldTextDidBeginEditingNotification या UITextViewTextDidBeginEditingNotification अधिसूचनाएं topMostViewController , तो मैं UIWindow.rootViewController पदानुक्रम से topMostViewController उदाहरण प्राप्त करने का प्रयास करता हूं। UITextField / UITextView को ठीक से उजागर करने के लिए, topMostViewController.view के फ्रेम को समायोजित करने की आवश्यकता है।

चरण 3: - मैंने पहले उत्तर दिए गए UITextField / UITextView संबंध में topMostViewController.view की अपेक्षित गति दूरी की गणना की।

चरण 4: - मैंने अनुमानित चाल दूरी के अनुसार topMostViewController.view.frame ऊपर / नीचे स्थानांतरित किया।

चरण 5: - यदि UIKeyboardWillHideNotification , UITextFieldTextDidEndEditingNotification या UITextViewTextDidEndEditingNotification अधिसूचना मिली है, तो मैं UIWindow.rootViewController पदानुक्रम से topMostViewController उदाहरण प्राप्त करने का प्रयास करता topMostViewController

topMostViewController.view 6: - मैंने topMostViewController.view की परेशान दूरी की गणना की है topMostViewController.view इसकी मूल स्थिति में बहाल करने की आवश्यकता है।

topMostViewController.view.frame : - मैंने परेशान दूरी के अनुसार topMostViewController.view.frame पुनर्स्थापित किया।

IQKeyboardManager : - मैंने ऐप लोड पर सिंगलटन IQKeyboardManager क्लास इंस्टेंस को IQKeyboardManager चालू किया, इसलिए ऐप में प्रत्येक UITextField / UITextView अपेक्षित चाल दूरी के अनुसार स्वचालित रूप से समायोजित हो जाएगा।

यह सब IQKeyboardManager आपके लिए कोड की कोई लाइन वास्तव में नहीं है !! केवल प्रोजेक्ट में संबंधित स्रोत फ़ाइल को खींचने और छोड़ने की आवश्यकता है। IQKeyboardManager डिवाइस अभिविन्यास , स्वचालित UIToolbar प्रबंधन , KeybkeyboardDistanceFromTextField का समर्थन करता है और आपके विचार से कहीं अधिक है।


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.


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.


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


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 .


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 .


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;
}

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;
}

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


This is the solution using Swift.

import UIKit

class ExampleViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var scrollView: UIScrollView!

    @IBOutlet var textField1: UITextField!
    @IBOutlet var textField2: UITextField!
    @IBOutlet var textField3: UITextField!
    @IBOutlet var textField4: UITextField!
    @IBOutlet var textField5: UITextField!

    var activeTextField: UITextField!

    // MARK: - View
    override func viewDidLoad() {
        super.viewDidLoad()
        self.textField1.delegate = self
        self.textField2.delegate = self
        self.textField3.delegate = self
        self.textField4.delegate = self
        self.textField5.delegate = self
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.registerForKeyboardNotifications()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        self.unregisterFromKeyboardNotifications()
    }

    // MARK: - Keyboard

    // Call this method somewhere in your view controller setup code.
    func registerForKeyboardNotifications() {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil)
        center.addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
    }

    func unregisterFromKeyboardNotifications () {
        let center:  NSNotificationCenter = NSNotificationCenter.defaultCenter()
        center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
        center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }

    // Called when the UIKeyboardDidShowNotification is sent.
    func keyboardWasShown (notification: NSNotification) {
        let info : NSDictionary = notification.userInfo!
        let kbSize = (info.objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue() as CGRect!).size

        let contentInsets: UIEdgeInsets = 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.
        var aRect = self.view.frame
        aRect.size.height -= kbSize.height;
        if (!CGRectContainsPoint(aRect, self.activeTextField.frame.origin) ) {
            self.scrollView.scrollRectToVisible(self.activeTextField.frame, animated: true)
        }
    }

    // Called when the UIKeyboardWillHideNotification is sent
    func keyboardWillBeHidden (notification: NSNotification) {
        let contentInsets = UIEdgeInsetsZero;
        scrollView.contentInset = contentInsets;
        scrollView.scrollIndicatorInsets = contentInsets;
    }

    // MARK: -  Text Field

    func textFieldDidBeginEditing(textField: UITextField) {
        self.activeTextField = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        self.activeTextField = nil
    }

}

Use this third party you don't need to write even one line

github.com/hackiftekhar/IQKeyboardManager

download project and drag and drop IQKeyboardManager in your project. If you find any issue please read README document.

Guys really its remove headache to manage keyboard ..

Thanks and best of luck!


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];
}




uikeyboard