कीबोर्ड दिखाई देने पर मैं UIScrollView को कैसे स्क्रॉल करूं?


107

मुझे अपने कोड से परेशानी हो रही है। UIScrollViewजब मैं संपादन कर रहा होता हूं तो उसे स्थानांतरित करने का प्रयास करता हूं, UITextFieldजिसे कीबोर्ड पॉप द्वारा छिपाया जाना चाहिए।

मैं अभी मुख्य फ्रेम को आगे बढ़ा रहा हूं क्योंकि मुझे नहीं पता कि कोड में 'स्क्रॉल अप' कैसे किया जाए। इसलिए, मैंने थोड़ा सा कोड किया था, यह ठीक काम कर रहा है, लेकिन जब मैं एक UItextfield को संपादित करता हूं और मैं UITextField'रिटर्न' बटन को दबाए बिना दूसरे पर स्विच करता हूं तो मुख्य दृश्य दूर तक waaayyyyy जाता है।

NSLog()जैसा कि आप नीचे देख सकते हैं मैंने अपने चर आकार, दूरी और textFieldRect.origin.y के साथ किया। जब मैं UITextFieldएक ही स्थान (y मूल) पर दो डालता हूं और मैं यह विशेष रूप से 'स्विच' (wihtout दबाने वाला रिटर्न) करता हूं, तो मुझे समान संख्याएं मिलती हैं, जबकि मेरा कोड पहले UITextFieldसंपादन के लिए ठीक काम करता था लेकिन दूसरे संपादन के लिए नहीं।

इसकी जांच करें:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
{
    int size;
    CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
    size = textFieldRect.origin.y + textFieldRect.size.height;
    if (change == FALSE)
    {
        size = size - distance;
    }
    if (size < PORTRAIT_KEYBOARD_HEIGHT)
    {
        distance = 0;
    }
    else if (size > PORTRAIT_KEYBOARD_HEIGHT)
    {
        distance = size - PORTRAIT_KEYBOARD_HEIGHT + 5; // +5 px for more visibility
    }
    NSLog(@"origin %f", textFieldRect.origin.y);
    NSLog(@"size %d", size);
    NSLog(@"distance %d", distance);
    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y -= distance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
    change = FALSE;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    change = TRUE;
    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y += distance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
}

कोई विचार ?

जवाबों:


204

Apple से अनुशंसित तरीका है की को बदलने contentInsetके लिए UIScrollView। यह एक बहुत ही सुंदर समाधान है, क्योंकि आपको इसमें गड़बड़ नहीं करनी है contentSize। निम्नलिखित कोड को कीबोर्ड प्रोग्रामिंग गाइड से कॉपी किया जाता है , जहां इस मुद्दे की हैंडलिंग के बारे में बताया गया है। आपको इस पर एक नजर डालनी चाहिए।

// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];
   [[NSNotificationCenter defaultCenter] addObserver:self
             selector:@selector(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];
}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    UIEdgeInsets contentInsets = 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 application might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent    
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

स्विफ्ट संस्करण:

func registerForKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardAppear(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisappear(_:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

// Don't forget to unregister when done
deinit {
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

@objc func onKeyboardAppear(_ notification: NSNotification) {
    let info = notification.userInfo!
    let rect: CGRect = info[UIKeyboardFrameBeginUserInfoKey] as! CGRect
    let kbSize = rect.size

    let insets = UIEdgeInsetsMake(0, 0, kbSize.height, 0)
    scrollView.contentInset = insets
    scrollView.scrollIndicatorInsets = insets

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your application might not need or want this behavior.
    var aRect = self.view.frame;
    aRect.size.height -= kbSize.height;

    let activeField: UITextField? = [addressTextView, servicePathTextView, usernameTextView, passwordTextView].first { $0.isFirstResponder }
    if let activeField = activeField {
        if !aRect.contains(activeField.frame.origin) {
            let scrollPoint = CGPoint(x: 0, y: activeField.frame.origin.y-kbSize.height)
            scrollView.setContentOffset(scrollPoint, animated: true)
        }
    }
}

@objc func onKeyboardDisappear(_ notification: NSNotification) {
    scrollView.contentInset = UIEdgeInsets.zero
    scrollView.scrollIndicatorInsets = UIEdgeInsets.zero
}

2
आह अच्छा। Sry, मुझे नहीं मिला कि आप स्क्रॉलिंग भाग के बारे में बात कर रहे थे। हाँ, ActiveField आपके UITextField प्रॉपर्टी के लिए एक प्लेसहोल्डर है। तो इसे स्थानापन्न करें और पुनः प्रयास करें। आपको आकार बदलने की आवश्यकता नहीं है, अन्यथा टेक्स्टफिल्ड वास्तव में ऊंचाई में बड़ा हो जाएगा।
मसा

2
आप वास्तव में मौजूदा contentInsets.top को अधिलेखित नहीं करना चाहते हैं, यदि आप ऐसा करते हैं तो आपका दृष्टिकोण नेविगेशन के पीछे जा सकता है।
स्विफ्टआर्किटेक्ट

6
github.com/michaeltyson/TPKeyboardAvoiding यह सुपर सरल उपाय है
प्रमोद

2
activeField.frameरिश्तेदार फ्रेम में परिवर्तित करना अच्छा activeFieldहै क्योंकि इसके लिए तत्काल बच्चा नहीं होना चाहिए self.view। अपडेटेड कोड कुछ इस तरह दिखना चाहिए: CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; CGRect relativeFieldFrame = [activeField convertRect:activeField.frame toView:self.view]; if (!CGRectContainsPoint(aRect, relativeFieldFrame.origin) ) { CGPoint scrollPoint = CGPointMake(0.0, relativeFieldFrame.origin.y-kbSize.height); [self.mainView.scrollView setContentOffset:scrollPoint animated:YES]; }
paxx

4
मुझे UIKeyboardFrameEndUserInfoKeyiOS 11 पर कुंजी का उपयोग करना था क्योंकि UIKeyboardFrameBeginUserInfoKeyअक्सर मुझे शून्य की ऊंचाई देता था।
कोलिन

66

मैंने अभी इसे Xcode 7 (बीटा 6) पर iOS9 के लिए स्विफ्ट 2.0 के साथ लागू किया, यहाँ ठीक काम करता है।

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

func registerKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo!
    let keyboardSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue.size
    let contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets

    var viewRect = view.frame
    viewRect.size.height -= keyboardSize.height
    if CGRectContainsPoint(viewRect, textField.frame.origin) {
        let scrollPoint = CGPointMake(0, textField.frame.origin.y - keyboardSize.height)
        scrollView.setContentOffset(scrollPoint, animated: true)
    }
}

func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = UIEdgeInsetsZero
    scrollView.scrollIndicatorInsets = UIEdgeInsetsZero
}

स्विफ्ट 3 के लिए संपादित

लगता है जैसे आपको केवल contentInsetऔर scrollIndicatorInsetस्विफ्ट 3 को सेट करने की आवश्यकता है , स्क्रॉलिंग / कंटेंटऑफसेट स्वचालित रूप से किया जाता है।

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    registerKeyboardNotifications()
}

func registerKeyboardNotifications() {
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillShow(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillShow,
                                         object: nil)
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillHide(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillHide,
                                         object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardInfo = userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue
    let keyboardSize = keyboardInfo.cgRectValue.size
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}

func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

क्या आप अपना कोड स्पष्ट कर सकते हैं? मेरे पास दो टेक्स्ट फ़ील्ड हैं और एक बार जब मैं पहला संपादन करता हूं तो इसे नीचे स्क्रॉल करता हूं जबकि दूसरा टेक्स्टफिल्ड स्क्रॉल करता है।
कैन

IPad पर यह स्क्रॉल दृश्य को ऊपर की बजाय नीचे ले जाता है। किसी भी विचार वहाँ क्या हो रहा है?
जस्टिन वैलेली

2
@ द टेक्स्टफिल्ड को संदर्भित किया जाता है, एक ऐसा चर है जिसे आप अपने वर्तमान दृश्य के आधार पर अपने व्यूकंट्रोलर के लिए सेट करते हैं
जोहान्स

मुझे आश्चर्य है कि अब Apple ने हमारे लिए कीबोर्ड के ऊपर सक्रिय पाठ क्षेत्र को स्क्रॉल करने के लिए खुद को क्यों लिया।
पॉलव्स

2
में 4 कीबोर्ड पर देखें @objcWillShow और keyboardWillHide तरीके
रोनाल्डो अल्बर्टिनी

16

यहाँ सभी उत्तर परिदृश्य संभावनाओं के बारे में भूल जाते हैं। यदि आप इस तरह से काम करना चाहेंगे जब डिवाइस को परिदृश्य दृश्य में घुमाया जाए, तो आपको समस्याओं का सामना करना पड़ेगा।

यहाँ चाल यह है कि यद्यपि दृश्य अभिविन्यास के बारे में पता है, कीबोर्ड नहीं है। लैंडस्केप में इसका मतलब है, कीबोर्ड की चौड़ाई वास्तव में इसकी ऊंचाई और वीजा वर्सा है।

सामग्री इनसेट को बदलने के लिए सेब को अनुशंसित तरीके से संशोधित करने और इसे लैंडस्केप ओरिएंटेशन का समर्थन करने के लिए, मैं निम्नलिखित का उपयोग करने की सलाह दूंगा:

// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];
   [[NSNotificationCenter defaultCenter] addObserver:self
             selector:@selector(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];
}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
        CGSize origKeySize = keyboardSize;
        keyboardSize.height = origKeySize.width;
        keyboardSize.width = origKeySize.height;
    }
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
    scroller.contentInset = contentInsets;
    scroller.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your application might not need or want this behavior.
    CGRect rect = scroller.frame;
    rect.size.height -= keyboardSize.height;
    NSLog(@"Rect Size Height: %f", rect.size.height);

    if (!CGRectContainsPoint(rect, activeField.frame.origin)) {
        CGPoint point = CGPointMake(0, activeField.frame.origin.y - keyboardSize.height);
        NSLog(@"Point Height: %f", point.y);
        [scroller setContentOffset:point animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent    
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

यहाँ ध्यान देने वाला भाग निम्नलिखित है:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
    CGSize origKeySize = keyboardSize;
    keyboardSize.height = origKeySize.width;
    keyboardSize.width = origKeySize.height;
}

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


अच्छी तरह से, तो आप इस प्रति सामग्री इनसेट नीचे के अतिरिक्त समायोजन (कमी) कार्य करना चाहेंगे stackoverflow.com/questions/25704513/... मामले स्क्रोलर स्क्रीन UIEdgeInsetsMake (0.0, 0.0, kbSize.height की पूरी ऊंचाई कब्जे में - ([यूआईस्क्रीन मेनस्क्रीन] ।bounds.size.height - cvf.origin.y - cvf.size.height), 0.0); जहां cvf scroller.frame है
एंटोन ट्रोपास्को

if (ओरिएंटेशन == UIInterfaceOrientationLandscapeLeft || ओरिएंटेशन == UIInterfaceOrientationLandscapeRight )
schmidt9

13

स्विफ्ट 4 समाधान:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    registerKeyboardNotifications()
}

func registerKeyboardNotifications() {
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillShow(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillShow,
                                         object: nil)
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillHide(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillHide,
                                         object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardInfo = userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue
    let keyboardSize = keyboardInfo.cgRectValue.size
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}

@objc func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

3
ज्यादातर, बस बदलने के लिए की जरूरत है काम UIKeyboardFrameBeginUserInfoKeyकरने के लिएUIKeyboardFrameEndUserInfoKey
Fonix

मैं UITableView में इस कोड को लागू करता हूं। लेकिन TableView तुरंत स्क्रॉल नहीं कर रहा है।
शॉन बेक

3
UIKeyboardWillShow, UIKeyboardWillHide, और UIKeyboardFrameBeginUserInfoKeyनाम दिया गया है UIResponder.keyboardWillShowNotification, UIResponder.keyboardWillHideNotificationऔर UIResponder.keyboardFrameBeginUserInfoKey
हारून ब्रेजर

9

इस सामान के लिए कोडिंग की बहुत ज़रूरत नहीं है, यह नीचे दिए गए कोड की तरह बहुत आसान है: -

इस तरह की छवि से आपके सभी टेक्स्ट UIScrollview में हैं: -

यहां छवि विवरण दर्ज करें

YourViewController.h

@interface cntrInquiryViewController : UIViewController<UIScrollViewDelegate,UITextFieldDelegate>
{
     IBOutlet UITextField *txtName;
     IBOutlet UITextField *txtEmail;
     IBOutlet UIScrollView *srcScrollView;
}
@end

IBOutlet को nib से कनेक्ट करें और NIB से UItextfiled और स्क्रॉलव्यू प्रतिनिधि के प्रत्येक प्रतिनिधि को भी कनेक्ट करें

-(void)viewWillAppear:(BOOL)animated
{
    srcScrollView.contentSize = CGSizeMake(320, 500);

    [super viewWillAppear:YES];
}


-(void)textFieldDidBeginEditing:(FMTextField *)textField
{
    [srcScrollView setContentOffset:CGPointMake(0,textField.center.y-140) animated:YES];//you can set your  y cordinate as your req also
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
     [textField resignFirstResponder];
     [srcScrollView setContentOffset:CGPointMake(0,0) animated:YES];


    return YES;
}

ध्यान दें कि यदि पाठ-दायर प्रतिनिधि जुड़ा हुआ नहीं है, तो कोई भी एक विधि काम नहीं कर रही है जो सुनिश्चित करें कि सभी iBOulate और प्रतिनिधि सही तरीके से जुड़े हों


5
यह बहुत पुराना तरीका है और इसका इस्तेमाल नहीं किया जाना चाहिए। यह हार्कोडेड मूल्यों और मान्यताओं पर निर्भर करता है जो अब प्रासंगिक नहीं हैं।
Womble

@Womble ऐसे कई उत्तर हैं जो पुराने हैं लेकिन उस समय के प्रश्न के लिए प्रासंगिक हैं (जब प्रश्न पूछा गया था)। तो, कारणों के बिना नीचे मत देना।
आशीष कक्कड़

7

IOS में ऑटो लेआउट के साथ Swift + UIScrollView का उपयोग करते हुए Apple की सिफारिश फिर से शुरू हुई (इन निम्नलिखित लिंक पर लिंक करना: लिंक 1 , लिंक 2 , लिंक 3 ):

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var t1: UITextField!
    @IBOutlet var t2: UITextField!
    @IBOutlet var t3: UITextField!
    @IBOutlet var t4: UITextField!

    @IBOutlet var srcScrollView: UIScrollView!

    @IBOutlet var contentView: UIView!

    var contentViewCoordinates: CGPoint!

    override func viewDidLoad() {

        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        /* Constraints on content view */
        let leftConstraint = NSLayoutConstraint(item:self.contentView,
            attribute:NSLayoutAttribute.Leading,
            relatedBy:NSLayoutRelation.Equal,
            toItem:self.view,
            attribute:NSLayoutAttribute.Left,
            multiplier:1.0,
            constant:0)
        self.view.addConstraint(leftConstraint)

        let rightConstraint = NSLayoutConstraint(item:self.contentView,
            attribute:NSLayoutAttribute.Trailing,
            relatedBy:NSLayoutRelation.Equal,
            toItem:self.view,
            attribute:NSLayoutAttribute.Right,
            multiplier:1.0,
            constant:0)
        self.view.addConstraint(rightConstraint)

        /* Tap gesture */
        let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard")
        // prevents the scroll view from swallowing up the touch event of child buttons
        tapGesture.cancelsTouchesInView = false
        srcScrollView.addGestureRecognizer(tapGesture)

        /* Save content view coordinates */
        contentViewCoordinates = contentView.frame.origin
    }

    func hideKeyboard() {
        t1.resignFirstResponder()
        t2.resignFirstResponder()
        t3.resignFirstResponder()
        t4.resignFirstResponder()
    }

    var activeField: UITextField?

    func textFieldDidBeginEditing(textField: UITextField) {
        activeField = textField
    }

    func textFieldDidEndEditing(textField: UITextField) {
        activeField = nil
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        let center = NSNotificationCenter.defaultCenter()
        center.addObserver(self, selector: "keyboardOnScreen:", name: UIKeyboardDidShowNotification, object: nil)
        center.addObserver(self, selector: "keyboardOffScreen:", name: UIKeyboardDidHideNotification, object: nil)
    }

    func keyboardOnScreen(notification: NSNotification){
        // Retrieve the size and top margin (inset is the fancy word used by Apple) 
        // of the keyboard displayed.
        let info: NSDictionary  = notification.userInfo!
        let kbSize = info.valueForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue().size
        let contentInsets: UIEdgeInsets  = UIEdgeInsetsMake(0.0, 0.0, kbSize!.height, 0.0)

        srcScrollView.contentInset = contentInsets
        srcScrollView.scrollIndicatorInsets = contentInsets

        var aRect: CGRect = self.view.frame
        aRect.size.height -= kbSize!.height
        //you may not need to scroll, see if the active field is already visible
        if (CGRectContainsPoint(aRect, activeField!.frame.origin) == false) {
            let scrollPoint:CGPoint = CGPointMake(0.0, activeField!.frame.origin.y - kbSize!.height)
            srcScrollView.setContentOffset(scrollPoint, animated: true)
        }
    }

//    func keyboardOnScreen(aNotification: NSNotification) {
//        let info: NSDictionary  = aNotification.userInfo!
//        let kbSize = info.valueForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue().size
//        
//        var bkgndRect: CGRect! = activeField?.superview?.frame
//        
//        bkgndRect.size.height += kbSize!.height
//        
//        activeField?.superview?.frame = bkgndRect
//        
//        srcScrollView.setContentOffset(CGPointMake(0.0, activeField!.frame.origin.y - kbSize!.height), animated: true)
//    }

    func keyboardOffScreen(notification: NSNotification){
        let contentInsets:UIEdgeInsets = UIEdgeInsetsZero

        srcScrollView.contentInset = contentInsets
        srcScrollView.scrollIndicatorInsets = contentInsets

        self.srcScrollView.setContentOffset(CGPointMake(0, -self.view.frame.origin.y/2), animated: true)
    }

}

एक दिन की कड़ी मेहनत के बाद मैंने स्विफ्ट में ऐप्पल की सिफारिश को लागू करने में कामयाबी हासिल की + उनके कोड को थोड़ा संशोधित किया + इसे सभी सेब उपकरणों पर उत्तरदायी बना दिया, इसलिए वोटिंग से पहले कृपया मुझे बताएं कि क्यों। उपरोक्त कोई भी कोड सभी उपकरणों और सभी लेआउट स्थितियों पर सही ढंग से काम नहीं करता है। हालाँकि मेरा काम सभी सेब उपकरणों और लेआउट स्थितियों पर काम करता है।
राजा-जादूगर

मुझे लगता है कि दृश्य मरने से पहले आपको सूचना केंद्र से सदस्यता समाप्त करने की आवश्यकता है?
सिरिल डचोन-डोरिस

4

केवल एक चीज जो मैं Apple कोड में अपडेट करूंगा वह है कीबोर्डव्हीलबीड: विधि, सुचारु रूप से संक्रमण प्रदान करने के लिए।

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;

    [UIView animateWithDuration:0.4 animations:^{
        self.scrollView.contentInset = contentInsets;
    }];
    self.scrollView.scrollIndicatorInsets = contentInsets;

}

4

यहां एक स्विफ्ट 3 संगत उत्तर है, जो एक नेविगेशन नियंत्रक के भीतर दृश्य नियंत्रकों के साथ भी काम करेगा - क्योंकि वे स्क्रॉल दृश्य contentInset.topसंपत्ति को बदल देंगे ।

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.registerKeyboardNotifications()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.unregisterKeyboardNotifications()
}

func registerKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(LoginViewController.keyboardDidShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(LoginViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func unregisterKeyboardNotifications() {
    NotificationCenter.default.removeObserver(self)
}


func keyboardDidShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardInfo = userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue
    let keyboardSize = keyboardInfo.cgRectValue.size

    // Get the existing contentInset for the scrollView and set the bottom property to be the height of the keyboard
    var contentInset = self.scrollView.contentInset
    contentInset.bottom = keyboardSize.height

    self.scrollView.contentInset = contentInset
    self.scrollView.scrollIndicatorInsets = contentInset
}

func keyboardWillHide(notification: NSNotification) {
    var contentInset = self.scrollView.contentInset
    contentInset.bottom = 0

    self.scrollView.contentInset = contentInset
    self.scrollView.scrollIndicatorInsets = UIEdgeInsets.zero
}

4

UIToolbar और UITabBar की संभावित ऊंचाइयों को ध्यान में रखते हुए 4.2 समाधान।

private func setupKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIControl.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIControl.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWillShow(_ notification: Notification) {
    let userInfo: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardSize = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size

    let tabbarHeight = tabBarController?.tabBar.frame.size.height ?? 0
    let toolbarHeight = navigationController?.toolbar.frame.size.height ?? 0
    let bottomInset = keyboardSize.height - tabbarHeight - toolbarHeight

    scrollView.contentInset.bottom = bottomInset
    scrollView.scrollIndicatorInsets.bottom = bottomInset
}

@objc func keyboardWillHide(_ notification: Notification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

और, यदि आप <iOS 9 को लक्षित कर रहे हैं, तो आपको किसी बिंदु पर पर्यवेक्षक को अपंजीकृत करना होगा (धन्यवाद जो )


क्या यह iPhone X पर टैब्बर के तहत खाते की जगह लेता है? यह वह जगह है जहां आईओएस पट्टी दिखाई देती है।
सर्फ़राइड

iOS9 + आप पर्यवेक्षक को दूर करने की जरूरत नहीं है developer.apple.com/documentation/foundation/notificationcenter/...
जो

हाँ तुम सही हो। मैंने उसी हिसाब से जवाब अपडेट किया है।
JanApotheker

3

मैंने पाया है कि उपरोक्त उत्तर पुराने हो चुके हैं। स्क्रॉल करते समय भी सही नहीं।

यहां एक स्विफ्ट संस्करण है।

यह TextField के नीचे स्क्रॉल करेगा, कोई अतिरिक्त स्थान नहीं। और यह उस तरह से बहाल हो जाएगा जैसे कि यह पहली बार दिखाई दिया था।

//add observer
override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ARVHttpPlayVC.keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ARVHttpPlayVC.keyboardDidHide(_:)), name: UIKeyboardDidHideNotification, object: nil)
}

func keyboardDidShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo!
    let keyboardSize = userInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)!.CGRectValue.size
    let difference = keyboardSize.height - (self.view.frame.height - inputTextField.frame.origin.y - inputTextField.frame.size.height)
    if difference > 0 {
        var contentInset:UIEdgeInsets = self.scrollView.contentInset
        contentInset.bottom = difference
        self.scrollView.contentInset = contentInset

        let scrollPoint = CGPointMake(0, difference)
        self.scrollView.setContentOffset(scrollPoint, animated: true)
    }

}

func keyboardDidHide(notification: NSNotification) {
    let contentInset:UIEdgeInsets = UIEdgeInsetsZero
    self.scrollView.contentInset = contentInset
}

//remove observer
deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

यह थोड़ा स्क्रॉल करता है, लेकिन पूरी ऊंचाई को उजागर करने के लिए पर्याप्त नहीं है। मैं स्विफ्ट 2.3 का उपयोग कर रहा हूं और इसे iphone 5 पर परीक्षण कर रहा हूं
KMC

2

यह वही है जो मैं उपयोग कर रहा हूं। यह सरल है और यह अच्छी तरह से काम करता है।

#pragma mark - Scrolling

-(void)scrollElement:(UIView *)view toPoint:(float)y
{
    CGRect theFrame = view.frame;
    float orig_y = theFrame.origin.y;
    float diff = y - orig_y;

    if (diff < 0) 
        [self scrollToY:diff];

    else 
        [self scrollToY:0];
}

-(void)scrollToY:(float)y
{
    [UIView animateWithDuration:0.3f animations:^{
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        self.view.transform = CGAffineTransformMakeTranslation(0, y);
    }];
}

अपने दृश्य को ऊपर की ओर शिफ्ट करने के लिए UITextFieldडेलिगेट कॉल textFieldDidBeginEditing:का उपयोग करें , और कीबोर्ड के बंद होने पर दृश्य को सामान्य पर वापस करने के लिए एक अधिसूचना पर्यवेक्षक भी जोड़ें:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    if (self.view.frame.origin.y == 0)
        [self scrollToY:-90.0];  // y can be changed to your liking

}

-(void)keyboardWillHide:(NSNotification*)note
{
    [self scrollToY:0];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

2

यह स्विफ्ट में सुधार के साथ अंतिम कोड है

    //MARK: UITextFieldDelegate
func textFieldDidBeginEditing(textField: UITextField!) {    //delegate method
    self.textField = textField
}

func textFieldShouldReturn(textField: UITextField!) -> Bool {   //delegate method
    textField.resignFirstResponder()
    return true
}

//MARK: Keyboard handling
override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    unregisterKeyboardNotifications()
}

func registerKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(UCProfileSettingsViewController.keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(UCProfileSettingsViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)
}

func unregisterKeyboardNotifications() {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardDidShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo!
    let keyboardSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue.size
    let contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets

    var viewRect = self.view.frame
    viewRect.size.height -= keyboardSize.height
    let relativeFieldFrame: CGRect = textField.convertRect(textField.frame, toView: self.view)
    if CGRectContainsPoint(viewRect, relativeFieldFrame.origin) {
        let scrollPoint = CGPointMake(0, relativeFieldFrame.origin.y - keyboardSize.height)
        scrollView.setContentOffset(scrollPoint, animated: true)
    }

}

func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = UIEdgeInsetsZero
    scrollView.scrollIndicatorInsets = UIEdgeInsetsZero
}

1
मुझे लगता है कि आपका तर्क उल्टा है - आप केवल स्क्रॉल करना चाहते हैं यदि CGRectContainsPoint में रिश्तेदार नहीं होता हैFrame.origin।
रेफ्लेक

2

सबसे आसान समाधानों में से एक निम्नलिखित प्रोटोकॉल का उपयोग कर रहा है:

protocol ScrollViewKeyboardDelegate: class {
    var scrollView: UIScrollView? { get set }

    func registerKeyboardNotifications()
    func unregisterKeyboardNotifications()
}

extension ScrollViewKeyboardDelegate where Self: UIViewController {
    func registerKeyboardNotifications() {
        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillChangeFrameNotification,
            object: nil,
            queue: nil) { [weak self] notification in
                self?.keyboardWillBeShown(notification)
        }

        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillHideNotification,
            object: nil,
            queue: nil) { [weak self] notification in
                self?.keyboardWillBeHidden(notification)
        }
    }

    func unregisterKeyboardNotifications() {
        NotificationCenter.default.removeObserver(
            self,
            name: UIResponder.keyboardWillChangeFrameNotification,
            object: nil
        )
        NotificationCenter.default.removeObserver(
            self,
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }

    func keyboardWillBeShown(_ notification: Notification) {
        let info = notification.userInfo
        let key = (info?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)
        let aKeyboardSize = key?.cgRectValue

        guard let keyboardSize = aKeyboardSize,
            let scrollView = self.scrollView else {
                return
        }

        let bottomInset = keyboardSize.height
        scrollView.contentInset.bottom = bottomInset
        scrollView.scrollIndicatorInsets.bottom = bottomInset
        if let activeField = self.view.firstResponder {
            let yPosition = activeField.frame.origin.y - bottomInset
            if yPosition > 0 {
                let scrollPoint = CGPoint(x: 0, y: yPosition)
                scrollView.setContentOffset(scrollPoint, animated: true)
            }
        }
    }

    func keyboardWillBeHidden(_ notification: Notification) {
        self.scrollView?.contentInset = .zero
        self.scrollView?.scrollIndicatorInsets = .zero
    }
}

extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }
        return subviews.first(where: {$0.firstResponder != nil })
    }
}

जब आप इस प्रोटोकॉल का उपयोग करना चाहते हैं, तो आपको केवल इसके अनुरूप होना चाहिए और अपने नियंत्रक में अपने स्क्रॉल दृश्य को निम्नानुसार असाइन करना होगा:

class MyViewController: UIViewController {
      @IBOutlet var scrollViewOutlet: UIScrollView?
      var scrollView: UIScrollView?

      public override func viewDidLoad() {
        super.viewDidLoad()

        self.scrollView = self.scrollViewOutlet
        self.scrollView?.isScrollEnabled = true
        self.registerKeyboardNotifications()
    }

    extension MyViewController: ScrollViewKeyboardDelegate {}

    deinit {
       self.unregisterKeyboardNotifications()
    }

}

1

मैं ऐसा ही करूंगा। यह बहुत कोड है, लेकिन यह सुनिश्चित करता है, कि वर्तमान में फ़ोकस में मौजूद TextField 'उपलब्ध स्पेस' में लंबवत केंद्रित है:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[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];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];
    NSValue *keyBoardEndFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGSize keyboardSize = [keyBoardEndFrame CGRectValue].size;
    self.keyboardSize = keyboardSize;

    [self adjustScrollViewOffsetToCenterTextField:self.currentTextField];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    self.keyboardSize = CGSizeZero;
}

- (IBAction)textFieldGotFocus:(UITextField *)sender {
    sender.inputAccessoryView = self.keyboardAccessoryView;
    self.currentTextField = sender;
    [self adjustScrollViewOffsetToCenterTextField:sender];    
}

- (void)adjustScrollViewOffsetToCenterTextField:(UITextField *)textField
{
    CGRect textFieldFrame = textField.frame;
    float keyboardHeight = MIN(self.keyboardSize.width, self.keyboardSize.height);

    float visibleScrollViewHeight = self.scrollView.frame.size.height - keyboardHeight;
    float offsetInScrollViewCoords = (visibleScrollViewHeight / 2) - (textFieldFrame.size.height / 2);

    float scrollViewOffset = textFieldFrame.origin.y - offsetInScrollViewCoords;


    [UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x, scrollViewOffset);
    }completion:NULL];

}

you'll need these two properties in your @interface...
@property (nonatomic, assign) CGSize keyboardSize;
@property (nonatomic, strong) UITextField *currentTextField;

ध्यान दें कि - (IBAction)textFieldGotFocus:कार्रवाई प्रत्येक टेक्स्टफिल्ड पर आदी हैDidBeginEditing स्थिति पर ।

इसके अलावा कीबोर्ड अधिसूचना से एनीमेशन की अवधि प्राप्त करना और एक निश्चित मूल्य के बजाय स्क्रॉलव्यू एनीमेशन के लिए उपयोग करना बेहतर होगा, लेकिन मुझे मुकदमा करना, यह मेरे लिए काफी अच्छा था;)


1

यदि आप बहुत अधिक गणना नहीं करना चाहते हैं, तो निम्नलिखित एक्सटेंशन का उपयोग करें:

func scrollSubviewToBeVisible(subview: UIView, animated: Bool) {
    let visibleFrame = UIEdgeInsetsInsetRect(self.bounds, self.contentInset)
    let subviewFrame = subview.convertRect(subview.bounds, toView: self)
    if (!CGRectContainsRect(visibleFrame, subviewFrame)) {
        self.scrollRectToVisible(subviewFrame, animated: animated)
    }
}

और शायद आप चाहते हैं कि आपका UITextField हमेशा दिखाई दे:

func textViewDidChange(textView: UITextView) {
    self.scrollView?.scrollSubviewToBeVisible(textView, animated: false)
}

1

स्विफ्ट 3 में इस कोड को आज़माएं:

override func viewDidAppear(_ animated: Bool) {
    setupViewResizerOnKeyboardShown()
}

func setupViewResizerOnKeyboardShown() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.keyboardWillShowForResizing),
                                           name: Notification.Name.UIKeyboardWillShow,
                                           object: nil)
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.keyboardWillHideForResizing),
                                           name: Notification.Name.UIKeyboardWillHide,
                                           object: nil)
}

func keyboardWillShowForResizing(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
        let window = self.view.window?.frame {
        // We're not just minusing the kb height from the view height because
        // the view could already have been resized for the keyboard before
        self.view.frame = CGRect(x: self.view.frame.origin.x,
                                 y: self.view.frame.origin.y,
                                 width: self.view.frame.width,
                                 height: window.origin.y + window.height - keyboardSize.height)

    } else {
        debugPrint("We're showing the keyboard and either the keyboard size or window is nil: panic widely.")
    }
}

func keyboardWillHideForResizing(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let viewHeight = self.view.frame.height
        self.view.frame = CGRect(x: self.view.frame.origin.x,
                                 y: self.view.frame.origin.y,
                                 width: self.view.frame.width,
                                 height: viewHeight) //viewHeight + keyboardSize.height

    } else {
        debugPrint("We're about to hide the keyboard and the keyboard size is nil. Now is the rapture.")
    }
}

deinit {
        NotificationCenter.default.removeObserver(self)
    }

1

ऊपर दिए गए मासा समाधान के आधार पर स्विफ्ट 5 समाधान - इसके संबंध में परिवर्तन:

  • keyboardFrameEndUserInfoKeyइसके बजाय का उपयोग करना keyboardFrameBeginUserInfoKey, क्योंकि keyboardFrameBeginUserInfoKeyपहले उदाहरण में वर्णित अन्य मूल्य को वापस दिखा सकते हैं: दिखाई देते समय कीबोर्ड की ऊंचाई भिन्न होती है
  • "विल" के बजाय "किया" सूचनाओं का उपयोग करके इसे 5 कुंजी नामों में स्विफ्ट करने के लिए बदल दिया गया: UIResponder.keyboardWillShowNotification/ के UIResponder.keyboardWillHideNotificationबजाय NSNotification.Name.UIKeyboardDidShow/NSNotification.Name.UIKeyboardDidHide

कोड:

override func viewDidLoad() {
    super.viewDidLoad()
    registerForKeyboardNotifications()
}

func registerForKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardAppear(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(onKeyboardDisappear(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func onKeyboardAppear(_ notification: NSNotification) {
    guard let info = notification.userInfo, let kbSize = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size else { return }

    let insets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0)

    scrollView.contentInset = insets
    scrollView.scrollIndicatorInsets = insets

    //Other changes if needed
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

0

आपको वास्तव में ऐसा करने के लिए UIScrollView की आवश्यकता नहीं है। मैंने इस कोड का उपयोग किया है और यह मेरे लिए काम करता है:

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

   if (textField==_myTextField)
   {
      [self keyBoardAppeared];
   }
   return true;
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
   if (textField==_myTextField)
   {
      [self keyBoardDisappeared];
   }
}

-(void) keyBoardAppeared
{
   CGRect frame = self.view.frame;

[UIView animateWithDuration:0.3
                      delay:0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
                     self.view.frame = CGRectMake(frame.origin.x, frame.origin.y-215, frame.size.width, frame.size.height);
                 }
                 completion:^(BOOL finished){

                 }];
}

-(void) keyBoardDisappeared
{
   CGRect frame = self.view.frame;

  [UIView animateWithDuration:0.3
                      delay:0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
                     self.view.frame = CGRectMake(frame.origin.x, frame.origin.y+215, frame.size.width, frame.size.height);
                 }
                 completion:^(BOOL finished){

                 }];
}

समस्याएं: हार्ड-कोडित मूल्यों का उपयोग करता है। अपने पूरे UI को ऊपर और नीचे शिफ्ट करता है जो अक्सर दृश्य के रूप को गड़बड़ कर देगा।
अर्थ-मामले

0

आप संपत्ति का उपयोग करके स्क्रॉल कर सकते हैं contentOffsetमें UIScrollView, जैसे,

CGPoint offset = scrollview.contentOffset;
offset.y -= KEYBOARD_HEIGHT + 5;
scrollview.contentOffset = offset;

एनिमेटेड स्क्रॉलिंग करने की भी एक विधि है।

इस कारण से कि आपका दूसरा संपादन सही तरीके से स्क्रॉल नहीं हो रहा है, ऐसा इसलिए हो सकता है क्योंकि आपको लगता है कि संपादन शुरू होने पर हर बार एक नया कीबोर्ड दिखाई देगा। यदि आप "कीबोर्ड" दृश्यमान स्थिति के लिए पहले से ही समायोजित कर चुके हैं (और पलटकर देखने से पहले कीबोर्ड दृश्यता के लिए इसी तरह की जाँच कर सकते हैं)।

एक बेहतर समाधान कीबोर्ड अधिसूचना के लिए सुनने के लिए हो सकता है, उदाहरण के लिए:

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

0

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मुझे लगा कि यह दूसरों की मदद कर सकता है। मैं चाहता था कि मेरे पास मौजूद कुछ ऐप्स के लिए कुछ आसान हो जाए, इसलिए मैंने इसके लिए एक क्लास बनाई। आप चाहें तो इसे यहां डाउनलोड कर सकते हैं: https://github.com/sdernley/iOSTextFieldHandler

यह स्वयं के एक प्रतिनिधि के रूप में UITextFields के सभी स्थापित करने के रूप में सरल है

textfieldname.delegate = self;

और फिर इसे अपने स्क्रॉल नियंत्रक पर अपने स्क्रॉलव्यू और सबमिट बटन के नाम के साथ जोड़ें

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [iOSTextFieldHandler TextboxKeyboardMover:containingScrollView tf:textField btn:btnSubmit];
}

0

निम्नलिखित मेरे समाधान है जो काम करता है (5 कदम)

Step1: एक पर्यवेक्षक को पकड़ने के लिए जोड़ें जो UITEXTFIELD या UITEXTVIEW ShoudBeginEditing (जहां ऑब्जेक्ट आवक या ViewDidLoad है)।

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(updateActiveField:)
                                             name:@"UPDATE_ACTIVE_FIELD" object:nil];

Step2: जब एक अधिसूचना पोस्ट करें .. UBEXTECTELD या UITEXTV के दृश्य के साथ ShhouldBeginEditing

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView {

[[NSNotificationCenter defaultCenter] postNotificationName:@"UPDATE_ACTIVE_FIELD" 
                                                    object:textView];
return YES;
}

Step3: वह विधि जिसे (Step1 कॉल करता है) वर्तमान UITEXTFIELD या UITEXTVIEW असाइन करती है

-(void) updateActiveField: (id) sender {
    activeField = [sender object];
}

Step4: कीबोर्ड पर्यवेक्षक UIKeyboardWillShowNotification (चरण 1 के रूप में एक ही स्थान) जोड़ें

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];

और तरीके:

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);

    _currentEdgeInsets = self.layoutPanel.contentInset; // store current insets to restore them later
    self.layoutPanel.contentInset = contentInsets;
    self.layoutPanel.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    CGRect aRect =  self.view.frame;
    aRect.size.height -= kbSize.height;

    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    CGPoint p = [activeField convertPoint:activeField.bounds.origin toView:window];

    if (!CGRectContainsPoint(aRect, p) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y +kbSize.height);
       [self.layoutPanel setContentOffset:scrollPoint animated:YES];
       self.layoutPanel.scrollEnabled = NO;
    }
}

Step5: कीबोर्ड पर्यवेक्षक UIKeyboardWillHideNotification (चरण 1 के रूप में एक ही स्थान) जोड़ें

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

और तरीके:

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    self.layoutPanel.contentInset = _currentEdgeInsets;
    self.layoutPanel.scrollIndicatorInsets = _currentEdgeInsets;
    self.layoutPanel.scrollEnabled = YES;
}

पर्यवेक्षकों को हटाने के लिए याद रखें!


0

मैंने सुधीर पालचुरी https://stackoverflow.com/users/2873919/sudheer-palchuri https://stackoverflow.com/a/32583809/6193496 द्वारा आपूर्ति किए गए इस उत्तर का उपयोग किया

ViewDidLoad में, सूचनाएं दर्ज करें:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(DetailsViewController.keyboardWillShow(_:)), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(DetailsViewController.keyboardWillHide(_:)), name:UIKeyboardWillHideNotification, object: nil)

नीचे पर्यवेक्षक विधियों को जोड़ें जो कीबोर्ड दिखाई देने पर स्वचालित स्क्रॉलिंग करता है।

func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}

func keyboardWillShow(notification:NSNotification){

var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
keyboardFrame = self.view.convertRect(keyboardFrame, fromView: nil)

var contentInset:UIEdgeInsets = self.scrollView.contentInset
contentInset.bottom = keyboardFrame.size.height
self.scrollView.contentInset = contentInset
}

func keyboardWillHide(notification:NSNotification){

var contentInset:UIEdgeInsets = UIEdgeInsetsZero
self.scrollView.contentInset = contentInset
}

0

मेरे समाधान में 4 चरण हैं:
- चरण 1: कीबोर्ड दिखाई देने पर फ़ंक्शन सुनता है

- (void)keyboardWasShown:(NSNotification *)notification {
// Get the size of the keyboard.
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//top: 64 for navigation bar, 0 for without navigation
UIEdgeInsets contentInsets = UIEdgeInsetsMake(64, 0, keyboardSize.height, 0);
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}

- चरण 2: जब कीबोर्ड गायब हो जाता है तो फ़ंक्शन सुनता है

- (void)keyboardWillHide:(NSNotification *)notification {
//top: 64 for navigatiob bar
UIEdgeInsets contentInsets = UIEdgeInsetsMake(64, 0, 0, 0);
[_editScrollView setContentInset: contentInsets];
[_editScrollView setScrollIndicatorInsets: contentInsets];
}

- चरण 3: इन कार्यों को अधिसूचना केंद्र में जोड़ें:

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- चरण 4: सुनने को हटा दें जब दृश्य नियंत्रक गायब हो जाता है

- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.