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




objective-c uikeyboard (24)

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

मेरे पास 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
}

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


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

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

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

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


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.


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

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 .


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 .


  1. यदि आपके पास अब आईफोन स्क्रीन में फिट नहीं है तो आपको केवल ScrollView आवश्यकता होगी। (यदि आप स्क्रॉलव्यू को घटकों के पर्यवेक्षण के रूप में जोड़ रहे हैं। कीबोर्ड के आने पर TextField स्क्रॉल करने के लिए, तो इसकी आवश्यकता नहीं है।)

  2. कुंजीपटल द्वारा छुपाए बिना textfields दिखाने के लिए, जब भी कुंजीपटल दिखाया जाता है तो टेक्स्टफील्ड वाले दृश्य को ऊपर / नीचे ले जाना मानक तरीका है।

यहां कुछ नमूना कोड दिया गया है:

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

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
    }

}

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

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

यह आपके लिए सब कुछ करेगा, बस इन्हें अपने व्यू कंट्रोलर क्लास में डालें और 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()
}

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.


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!


Note : this answer assumes your textField is in a scrollView.

I prefer to deal with this using scrollContentInset and scrollContentOffset instead of messing with the frames of my view.

First let's listen for the keyboard notifications

//call this from viewWillAppear
-(void)addKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}
//call this from viewWillDisappear
-(void)removeKeyboardNotifications{
    [[NSNotificationCenter default
    Center] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

Next step is to keep a property that represents the current first responder (UITextfield/ UITextVIew that currently has the keyboard).

We use the delegate methods to set this property. If you're using another component, you will need something similar.

Note that for textfield we set it in didBeginEditing and for textView in shouldBeginEditing. This is because textViewDidBeginEditing gets called after UIKeyboardWillShowNotification for some reason.

-(BOOL)textViewShouldBeginEditing:(UITextView * )textView{
    self.currentFirstResponder = textView;
    return YES;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField{
    self.currentFirstResponder = textField;
}

Finally, here's the magic

- (void)keyboardWillShow:(NSNotification*)aNotification{
    NSDictionary* info = [aNotification userInfo];
    CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];


    /*if currentFirstResponder is overlayed by the keyboard, move it so it bottom ends where the keyboard begins*/
    if(self.currentFirstResponder){

        //keyboard origin in currentFirstResponderFrame
        CGPoint keyboardOrigin = [self.currentFirstResponder convertPoint:kbFrame.origin fromView:nil];

        float spaceBetweenFirstResponderAndKeyboard = abs(self.currentFirstResponder.frame.size.height-keyboardOrigin.y);

        //only scroll the scrollview if keyboard overlays the first responder
        if(spaceBetweenFirstResponderAndKeyboard>0){
            //if i call setContentOffset:animate:YES it behaves differently, not sure why
            [UIView animateWithDuration:0.25 animations:^{
                [self.scrollView setContentOffset:CGPointMake(0,self.scrollView.contentOffset.y+spaceBetweenFirstResponderAndKeyboard)];
            }];
        }
    }

    //set bottom inset to the keyboard height so you can still scroll the whole content

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbFrame.size.height, 0.0);
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;

}

- (void)keyboardWillHide:(NSNotification*)aNotification{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;
}

docs में प्रदान किए गए ऐप्पल के कार्यान्वयन का उपयोग करना वास्तव में सबसे अच्छा है। हालांकि, वे जो कोड प्रदान करते हैं वह दोषपूर्ण है। keyboardWasShown: WasShown में पाए गए हिस्से को बदलें keyboardWasShown: केवल निम्न टिप्पणियों के नीचे:

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

ऐप्पल के कोड के साथ समस्याएं ये हैं: (1) वे हमेशा गणना करते हैं कि बिंदु दृश्य के फ्रेम के भीतर है, लेकिन यह एक ScrollView , इसलिए यह पहले ही स्क्रॉल हो चुका है और आपको उस ऑफ़सेट के लिए खाते की आवश्यकता है:

origin.y -= scrollView.contentOffset.y

(2) वे कुंजीपटल की ऊंचाई से सामग्री ऑफसेट को स्थानांतरित करते हैं, लेकिन हम विपरीत चाहते हैं (हम स्क्रीन पर दिखाई देने वाली ऊंचाई से contentOffset ऑफसेट को स्थानांतरित करना चाहते हैं, न कि क्या नहीं है):

activeField.frame.origin.y-(aRect.size.height)

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

try this short trick...

 - (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 = textField.frame.origin.y / 2; // 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];
    }

Happy coding :)....


सार्वभौमिक समाधान के लिए , 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 का समर्थन करता है और आपके विचार से कहीं अधिक है।


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

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

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

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

मुझे UIScrollView के कई UITextFields UIScrollView साथ बहुत सी समस्याएं भी थीं, जिनमें से एक या अधिक कीबोर्ड संपादित करके उन्हें अस्पष्ट कर दिया जाएगा।

यहां कुछ चीजें हैं जिन पर विचार किया जाता है कि क्या आपका UIScrollView ठीक से स्क्रॉल नहीं UIScrollView है।

1) सुनिश्चित करें कि आपकी सामग्री आकार UIScrollView फ्रेम आकार से अधिक है। UIScrollViews को समझने का तरीका यह है कि UIScrollView ContentSize में परिभाषित सामग्री पर देखने वाली विंडो की तरह है। तो जब UIScrollview कहीं भी स्क्रॉल करने के लिए, सामग्री आकार UIScrollview से अधिक होना चाहिए। अन्यथा, कोई स्क्रॉलिंग आवश्यक नहीं है क्योंकि सामग्री में परिभाषित सब कुछ आकार पहले से ही दिखाई दे रहा है। बीटीडब्ल्यू, डिफ़ॉल्ट सामग्री आकार = CGSizeZero

2) अब जब आप समझते हैं कि UIScrollView वास्तव में आपकी "सामग्री" में एक विंडो है, यह सुनिश्चित करने का तरीका है कि कीबोर्ड आपके UIScrollView's "विंडो" को अस्पष्ट नहीं UIScrollView तो UIScrollView का आकार बदलना होगा ताकि जब कीबोर्ड मौजूद हो, तो आप UIScrollView विंडो को केवल मूल UIScrollView frame.size.height कीबोर्ड की ऊंचाई से घटाकर आकार दिया गया है। यह सुनिश्चित करेगा कि आपकी खिड़की केवल उस छोटे से देखने योग्य क्षेत्र है।

3) यहां पकड़ है: जब मैंने इसे पहली बार कार्यान्वित किया तो मुझे लगा कि मुझे संपादित CGRect का CGRect प्राप्त करना होगा और यूआईएसक्रोल UIScrollView's स्क्रॉलआरसीटीवी विज़िबल विधि को कॉल करना होगा। मैंने scrollRecToVisible विधि को कॉल के साथ UITextFieldDelegate विधि textFieldDidBeginEditing को कार्यान्वित किया। यह वास्तव में एक अजीब दुष्प्रभाव के साथ काम करता था कि स्क्रॉलिंग UITextField को स्थिति में UITextField लेगी। सबसे लंबे समय तक मैं यह नहीं समझ सका कि यह क्या था। तब मैंने textFieldDidBeginEditing डिलीगेट विधि को टिप्पणी की और यह सब काम !! (???)। जैसा कि यह निकला, मेरा मानना ​​है कि UIScrollView वास्तव में वर्तमान में संपादित UITextField को देखने योग्य खिड़की में स्पष्ट रूप से लाता है। UITextFieldDelegate विधि का मेरा कार्यान्वयन और scrollRecToVisible बाद की कॉल अनावश्यक थी और अजीब दुष्प्रभाव का कारण था।

तो जब कीबोर्ड दिखाई देता है तो UIScrollView में अपनी 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. देखने के लिए कीबोर्ड अधिसूचनाओं के लिए रजिस्टर करें
  2. ViewDidUnload पर कीबोर्ड nofitications के लिए पंजीकरण रद्द करें
  3. यह सुनिश्चित करें कि contentSize सेट है और आपके UIScrollView से अधिक UIScrollView पर viewDidLoad
  4. कुंजीपटल मौजूद होने पर UIScrollView को UIScrollView
  5. कुंजीपटल चला जाता है जब UIScrollView वापस वापस
  6. यह पता लगाने के लिए एक ivar का उपयोग करें कि कुंजीपटल स्क्रीन पर पहले से दिखाया गया है क्योंकि प्रत्येक बार जब UITextField को UITextField जाता है, तब भी कुंजीपटल अधिसूचनाएं भेजी जाती हैं, भले ही कीबोर्ड पहले से मौजूद हो, UIScrollView कम करने से बचने के लिए कीबोर्ड पहले से मौजूद है

ध्यान देने योग्य एक बात यह है कि जब आप किसी अन्य UITextField पर टैब करते हैं तो कुंजीपटल स्क्रीन पर पहले से ही UIKeyboardWillShowNotification आग लग जाएगा। जब कीबोर्ड पहले से स्क्रीन पर है, तो UIScrollView आकार बदलने से बचने के लिए मैंने ivar का उपयोग करके इसका ख्याल रखा। अनजाने में UIScrollView आकार बदलना जब कीबोर्ड पहले से ही विनाशकारी होगा!

उम्मीद है कि यह कोड आप में से कुछ को सिरदर्द बचाता है।


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.


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

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.





uikeyboard