[Ios] كيف يمكنني جعل UITextField يتحرك لأعلى عندما تكون لوحة المفاتيح موجودة؟


Answers

كنت أواجه أيضًا مشكلة كبيرة في إنشاء UITextFields متعددة ، حيث يتم حجب واحد أو أكثر منها بواسطة لوحة المفاتيح عند تعديلها.

فيما يلي بعض الأشياء الواجب مراعاتها إذا لم يتم تمرير UIScrollView الخاص بك بشكل صحيح.

1) تأكد من أن حجم المحتوى الخاص بك أكبر من حجم إطار UIScrollView . تتمثل طريقة فهم UIScrollViews أن UIScrollView يشبه نافذة عرض على المحتوى المحدد في contentSize. لذلك عندما تكون UIScrollview قابلة للتمرير في أي مكان ، يجب أن يكون contentSize أكبر من UIScrollView . عدا ذلك ، لا يوجد تمرير مطلوب لأن كل ما تم تعريفه في contentSize مرئي بالفعل. راجع للشغل ، CGSizeZero الافتراضيالحجم = CGSizeZero .

2) الآن بعد أن فهمت أن UIScrollView هو نافذة حقًا إلى "المحتوى" الخاص بك ، فإن طريقة التأكد من أن لوحة المفاتيح لا تحجب "نافذة" UIScrollView's الخاصة بك لعرض حجم UIScrollView حتى عندما تكون لوحة المفاتيح موجودة ، يكون حجم إطار UIScrollView إلى UIScrollView frame.size.height الأصلي ناقص ارتفاع لوحة المفاتيح. سيضمن ذلك أن تكون نافذتك هي تلك المنطقة الصغيرة القابلة للعرض فقط.

3) وإليك catch: عندما قمت أولاً بتطبيق هذا أحسب أنني يجب أن تحصل على CGRect من CGRect تحريرها و استدعاء الأسلوب scrollRecToVisible UIScrollView. قمت بتطبيق أسلوب UITextFieldDelegate مع استدعاء الأسلوب scrollRecToVisible . هذا عمل فعلا مع تأثير جانبي غريب أن التمرير سوف UITextField إلى موضعه. لأطول فترة لم أتمكن من معرفة ما كان عليه. ثم علقت على textFieldDidBeginEditing مفوض طريقة وكلها تعمل !! (؟؟؟). كما تبين ، أعتقد أن UITextField يعرض ضمنيا UITextField تم تعديله حاليًا إلى النافذة القابلة للعرض ضمنيًا. كان التنفيذ الخاص UITextFieldDelegate لأسلوب UITextFieldDelegate اللاحق scrollRecToVisible زائدا وكان السبب في التأثير الجانبي الغريب.

حتى هنا هي الخطوات اللازمة للتمرير بشكل صحيح الخاص بك UITextField في UITextField إلى المكان عندما تظهر لوحة المفاتيح.

// 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. سجل لإشعارات لوحة المفاتيح في viewDidLoad
  2. إلغاء التسجيل للحصول على nofitications لوحة المفاتيح في viewDidUnload
  3. تأكد من تعيين viewDidLoad في viewDidLoad
  4. تقليص UIScrollView عندما تكون لوحة المفاتيح موجودة
  5. العودة إلى الخلف UIScrollView عندما تختفي لوحة المفاتيح.
  6. استخدم ivar لاكتشاف ما إذا كانت لوحة المفاتيح تظهر بالفعل على الشاشة حيث يتم إرسال إشعارات لوحة المفاتيح في كل مرة يتم فيها وضع UITextField على لوحة المفاتيح حتى إذا كانت لوحة المفاتيح موجودة بالفعل لتجنب تقلص UIScrollView عندما تكون قد تقلصت بالفعل

شيء واحد يجب ملاحظته هو أن UIKeyboardWillShowNotification سيتم UIKeyboardWillShowNotification حتى عندما تكون لوحة المفاتيح موجودة بالفعل على الشاشة عندما تقوم بعلامة التبويب على UITextField آخر. اعتنقت ذلك باستخدام ivar لتجنب تغيير حجم UIScrollView عندما تكون لوحة المفاتيح بالفعل على الشاشة. تغيير حجم UIScrollView دون قصد عندما تكون لوحة المفاتيح بالفعل سيكون هناك كارثة!

آمل أن يحفظ هذا الكود بعضكم من الصداع.

Question

باستخدام iOS SDK:

لدي UIView مع UITextField s التي تظهر لوحة مفاتيح. أحتاجها لتكون قادرة على:

  1. السماح بالتمرير لمحتويات UIScrollView للاطلاع على حقول النص الأخرى بمجرد ظهور لوحة المفاتيح

  2. تلقائيا "القفز" (عن طريق التمرير لأعلى) أو تقصير

أعلم أنني بحاجة إلى UIScrollView . لقد حاولت تغيير فئة UIView إلى UIScrollView ولكن ما زلت غير قادر على التمرير في مربعات النص لأعلى أو لأسفل.

هل أحتاج إلى كل من UIView و UIScrollView ؟ هل يذهب أحد داخل الآخر؟

ما الذي يجب تنفيذه من أجل التمرير تلقائيًا إلى حقل النص النشط؟

من الناحية المثالية سيتم إنجاز الكثير من إعداد المكونات قدر الإمكان في Interface Builder. أود فقط كتابة رمز لما يحتاجه.

ملاحظة: يتم عرض UIView (أو UIScrollView ) التي أعمل معها بواسطة tabbar ( 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
}

ومع ذلك ، لا يؤدي ذلك إلى "نقل" أو توسيط حقول النص الأدنى في المنطقة المرئية ، وهو ما أود فعله حقًا.




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.




في [self animateTextField:textField up:YES] استدعاء الوظيفة [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)
    }



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.




@user271753

To get your view back to original add:

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



جرب هذا:

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



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




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
    }

}



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 .




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



بالنسبة إلى الحل الشامل ، كان هذا هو IQKeyboardManager لتطبيق IQKeyboardManager .

الخطوة 1: - UITextField إشعارات عالمية من UITextField و UITextView و UIKeyboard في فئة UIKeyboard . أسميها IQKeyboardManager .

الخطوة 2: - إذا تم العثور على UIKeyboardWillShowNotification ، UITextFieldTextDidBeginEditingNotification أو UITextViewTextDidBeginEditingNotification الإشعارات ، أحاول الحصول على topMostViewController مثيل من التسلسل الهرمي UIWindow.rootViewController . لكشف UITextField / UITextView بشكل صحيح عليه ، يجب topMostViewController.view إطار topMostViewController.view .

الخطوة 3: - حسبت مسافة الانتقال المتوقعة من topMostViewController.view فيما يتعلق بالرد الأول UITextField / UITextView .

الخطوة 4: - نقلت topMostViewController.view.frame أعلى / أسفل وفقا لمسافة التحرك المتوقعة.

Step5: - إذا تم العثور على UIKeyboardWillHideNotification أو UITextFieldTextDidEndEditingNotification أو UITextViewTextDidEndEditingNotification ، فأنا أحاول مرة أخرى الحصول على topMostViewController مثيل من التسلسل الهرمي UIWindow.rootViewController .

الخطوة 6: - حسبت المسافة المضطربة من topMostViewController.view والتي تحتاج إلى استعادة وضعها الأصلي.

Step7: - استعدت topMostViewController.view.frame لأسفل وفقا للمسافة المضطربة.

Step8: - أنا مثيل مثيل الطبقة IQKeyboardManager على تحميل التطبيق ، بحيث سيتم ضبط كل UITextField / UITextView في التطبيق تلقائيا وفقا لمسافة التحرك المتوقعة.

هذا كل ما يفعله IQKeyboardManager لك مع عدم وجود رمز من الكود حقا !! تحتاج فقط إلى سحب وإسقاط ملف المصدر ذات الصلة إلى المشروع. كما يدعم IQKeyboardManager Device Orientation ، و UIToolbar التلقائي ، و KeybkeyboardDistanceFromTextField وأكثر بكثير مما تعتقد.




للمبرمجين سويفت :

هذا سوف يقوم بكل شيء من أجلك ، فقط ضع هذه في فئة وحدة التحكم في العرض لديك وقم بتطبيق UITextFieldDelegate على جهاز العرض الخاص بك وقم بتعيين مندوب 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()
}



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!




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)




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.