जब टेक्स्ट फ़ील्ड का चयन किया जाता है तो UITableView स्क्रॉल करना


251

बहुत परीक्षण और त्रुटि के बाद, मैं सवाल पूछ रहा हूं। मैंने बहुत से लोगों को समान समस्याओं के साथ देखा है, लेकिन सही काम करने के लिए सभी उत्तर नहीं मिल सकते हैं।

मेरे पास एक है UITableViewजो कस्टम कोशिकाओं से बना है। कोशिकाएँ एक-दूसरे के बगल में 5 पाठ क्षेत्रों से बनी होती हैं (एक ग्रिड की तरह)।

जब मैं नीचे की ओर सेल को स्क्रॉल और एडिट करने की कोशिश करता UITableViewहूं, तो मैं अपने सेल को कीबोर्ड के ठीक ऊपर तैनात करने का प्रबंधन नहीं कर सकता।

मैंने कई उत्तर देखे हैं आकार बदलने के बारे में बात करते हुए, आदि ... लेकिन उनमें से किसी ने भी अभी तक अच्छी तरह से काम नहीं किया है।

क्या कोई ठोस कोड उदाहरण के साथ ऐसा करने का "सही" तरीका स्पष्ट कर सकता है?


11
इस प्रश्न के लिए एक समाधान को लागू करने के लिए यह Applle प्रलेखन चरणों की रूपरेखा तैयार करता है। http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
क्रिस

@ क्रिस यह लिंक बताता है कि यह iOS 4.0
Ba

यह कोड मददगार हो सकता है: gist.github.com/TimMedcalf/9505416
Landonandrey

Url के नीचे का अनुसरण करें, यह काम करेगा: stackoverflow.com/questions/48922266/…
वेंकटेश जी

जवाबों:


126

यदि आप UIViewController के बजाय UITableViewController का उपयोग करते हैं, तो यह स्वचालित रूप से ऐसा करेगा।


13
क्या आपने कोशिश की और पाया कि काम नहीं कर रहा है? या आपके लिए विश्वास करने के लिए समाधान बहुत सरल है? बस UIViewController के बजाय UITableViewController का विस्तार करें और टेक्स्टफिल्ड से युक्त सेल कीबोर्ड के ऊपर स्क्रॉल करेगा जब भी टेक्स्टफिल्ड पहला उत्तरदाता बन जाएगा। कोई अतिरिक्त कोड की आवश्यकता नहीं है।
सैम हो

3
हां, लेकिन विशेष रूप से iPad पर हमें ऐसा करने का एक तरीका चाहिए, जिसमें UITableViewController शामिल न हो।
बॉब स्प्रीन

13
स्पष्ट करने के लिए, इसका उचित उत्तर यह कहने के लिए नहीं है कि हर बार जब आप एक टेबलव्यू का उपयोग करते हैं तो उसे पूर्ण स्क्रीन की आवश्यकता होती है, विशेष रूप से आईपैड पर। वहाँ महान क्षुधा है कि ऐसा नहीं करते के उदाहरणों की भीड़ हैं। उदाहरण के लिए, ऐप्पल के कई स्वयं, iPad पर संपर्क ऐप सहित।
बॉब स्प्रीन

32
यह काम नहीं करेगा यदि आप [सुपर viewWillAppear: YES] को ओवरराइड करते हैं। इसके अलावा, यह काम करना चाहिए।
रामबेटिनो

18
यदि आप viewWillAppear को ओवरराइड करते हैं: (BOOL) एनिमेटेड, तो कॉल करना न भूलें [super viewWillAppear: animated]; :)
मेडेट्रिक पेटिट

93

स्क्रॉल करने वाला कार्य अधिक सरल हो सकता है:

- (void) textFieldDidBeginEditing:(UITextField *)textField {
    UITableViewCell *cell;

    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
    // Load resources for iOS 6.1 or earlier
        cell = (UITableViewCell *) textField.superview.superview;

    } else {
        // Load resources for iOS 7 or later
        cell = (UITableViewCell *) textField.superview.superview.superview; 
       // TextField -> UITableVieCellContentView -> (in iOS 7!)ScrollView -> Cell!
    }
    [tView scrollToRowAtIndexPath:[tView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

बस। कोई गणना नहीं।


2
और क्यों नहीं?! बस UITableViewScrollPositionTop को UITableViewScrollPositionMiddle से बदलें। आपको निश्चित रूप से दृश्य क्षेत्र को समायोजित करने के लिए UITableView को फिर से बेचना होगा।
मिहई दामियन

3
काम करने के लिए प्रतीत नहीं होता है अगर एक UITableViewController ने कीबोर्ड को दिखाए जाने पर रीसाइज़िंग टेबल व्यू का ध्यान रखा है: नियंत्रक दृश्यमान आकार को कम कर देता है contentInset, जिसे स्पष्ट रूप से पूछने पर visibleRowsया खाते में नहीं लिया जाता है indexPathsForVisibleRows
जूलियन डी।

16
तालिका दृश्य की अंतिम कुछ पंक्तियों के लिए काम नहीं करता है। कीबोर्ड अभी भी सभी पंक्तियों को अस्पष्ट करेगा जो कीबोर्ड के ऊपर स्क्रॉल नहीं किया जा सकता है।
एलेक्स ज़ावाटोन 19

3
तालिका की अंतिम कुछ पंक्तियों पर काम करने के लिए ऑटो-स्क्रॉल व्यवहार प्राप्त करने के लिए, पता लगाएँ कि ये पंक्तियाँ कब संपादित करना शुरू करती हैं, और एक निश्चित ऊंचाई के रिक्त दृश्य के साथ तालिका दृश्य के अंत में पाद लेख जोड़ें। यह टेबलव्यू को कोशिकाओं को सही जगह पर स्क्रॉल करने की अनुमति देगा।
संमियो २

10
जब तक आप यह सुनिश्चित नहीं कर लेते कि आप वास्तव में सेल में जा रहे हैं, तब तक कॉल की एक श्रृंखला के माध्यम से सेल की देखरेख अविश्वसनीय है। देखें stackoverflow.com/a/17757851/1371070 और stackoverflow.com/a/17758021/1371070
Cezar

70

मैं कुछ ऐसा ही कर रहा हूं यह सामान्य है, आपके कोड के लिए कुछ विशिष्ट गणना करने की आवश्यकता नहीं है। कोड पर टिप्पणी की जाँच करें:

MyUIViewController.h में

@interface MyUIViewController: UIViewController <UITableViewDelegate, UITableViewDataSource>
{
     UITableView *myTableView;
     UITextField *actifText;
}

@property (nonatomic, retain) IBOutlet UITableView *myTableView;
@property (nonatomic, retain) IBOutlet UITextField *actifText;

- (IBAction)textFieldDidBeginEditing:(UITextField *)textField;
- (IBAction)textFieldDidEndEditing:(UITextField *)textField;

-(void) keyboardWillHide:(NSNotification *)note;
-(void) keyboardWillShow:(NSNotification *)note;

@end

MyUIViewController.m में

@implementation MyUIViewController

@synthesize myTableView;
@synthesize actifText;

- (void)viewDidLoad 
{
    // Register notification when the keyboard will be show
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(keyboardWillShow:)
                                          name:UIKeyboardWillShowNotification
                                          object:nil];

    // Register notification when the keyboard will be hide
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(keyboardWillHide:)
                                          name:UIKeyboardWillHideNotification
                                          object:nil];
}

// To be link with your TextField event "Editing Did Begin"
//  memoryze the current TextField
- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
    self.actifText = textField;
}

// To be link with your TextField event "Editing Did End"
//  release current TextField
- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
    self.actifText = nil;
}

-(void) keyboardWillShow:(NSNotification *)note
{
    // Get the keyboard size
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];

    // Detect orientation
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect frame = self.myTableView.frame;

    // Start animation
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // Reduce size of the Table view 
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
        frame.size.height -= keyboardBounds.size.height;
    else 
        frame.size.height -= keyboardBounds.size.width;

    // Apply new size of table view
    self.myTableView.frame = frame;

    // Scroll the table view to see the TextField just above the keyboard
    if (self.actifText)
      {
        CGRect textFieldRect = [self.myTableView convertRect:self.actifText.bounds fromView:self.actifText];
        [self.myTableView scrollRectToVisible:textFieldRect animated:NO];
      }

    [UIView commitAnimations];
}

-(void) keyboardWillHide:(NSNotification *)note
{
    // Get the keyboard size
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];

    // Detect orientation
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect frame = self.myTableView.frame;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3f];

    // Increase size of the Table view 
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
        frame.size.height += keyboardBounds.size.height;
    else 
        frame.size.height += keyboardBounds.size.width;

    // Apply new size of table view
    self.myTableView.frame = frame;

    [UIView commitAnimations];
}

@end

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

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var activeText: UITextField!
    @IBOutlet weak var tableView: UITableView!

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

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

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

    func keyboardWillShow(note: NSNotification) {
        if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            var frame = tableView.frame
            UIView.beginAnimations(nil, context: nil)
            UIView.setAnimationBeginsFromCurrentState(true)
            UIView.setAnimationDuration(0.3)
            frame.size.height -= keyboardSize.height
            tableView.frame = frame
            if activeText != nil {
                let rect = tableView.convertRect(activeText.bounds, fromView: activeText)
                tableView.scrollRectToVisible(rect, animated: false)
            }
            UIView.commitAnimations()
        }
    }

    func keyboardWillHide(note: NSNotification) {
        if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            var frame = tableView.frame
            UIView.beginAnimations(nil, context: nil)
            UIView.setAnimationBeginsFromCurrentState(true)
            UIView.setAnimationDuration(0.3)
            frame.size.height += keyboardSize.height
            tableView.frame = frame
            UIView.commitAnimations()
        }
    }
}

सूचनाओं का उपयोग करते हुए और डिवाइस की अभिविन्यास को शामिल करते हुए कीबोर्ड की ऊंचाई प्राप्त करना बहुत बढ़िया था, इसके लिए धन्यवाद! स्क्रॉलिंग भाग ने किसी कारण से मेरे लिए काम नहीं किया, इसलिए मुझे इसका उपयोग करना पड़ा:[tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionMiddle animated: YES];
टैबर

7
मुझे लगता है कि यह सबसे अच्छा जवाब है। बहुत साफ। केवल दो चीजें: 1) आपका viewDidLoad [सुपर viewDidLoad] और 2 नहीं कह रहा है) मुझे फ्रेम पर कुछ टैब्बर गणित में होना चाहिए था। राइट लाइन्स। अन्यथा परिपूर्ण! धन्यवाद।
विषाक्त

3
यहाँ संशोधन MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate]; CGFloat tabBarHeight = appDelegate.tabBarController.tabBar.frame.size.height; टोक्सैक का वर्णन है: तब कीबोर्ड ऊंचाई से टैबब्राइट को हटा दें जहां भी आप कीबोर्ड ऊंचाई का उपयोग करते हैं।
स्टीव एन

1
यदि उपयोगकर्ता textfield पर अपने सही काम कर रहा है। लेकिन अगर उपयोगकर्ता रिटर्न की को दबाए बिना किसी अन्य टेक्स्टफील्ड पर टैप करता है तो उसके टेबलव्यू का कम आकार।
भाविन रमणी

1
@BhavinRamani ने सहमति व्यक्त की। मैंने यह याद रखने के लिए एक साधारण बूलियन संपत्ति जोड़ी कि क्या कीबोर्ड पहले से ही प्रदर्शित हो रहा है या नहीं, और अनावश्यक होने पर कोड को फिर से निष्पादित करना छोड़ दें।
डर्टी हेनरी

46

बार्टोलोमिएज सेमासिस्की समाधान के आधार पर स्विफ्ट 3 के लिए सबसे सरल समाधान :

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self)
}

// MARK: Keyboard Notifications

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.2, animations: {
        // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    })
}

एक मामूली विस्तार ... के Notificationबजाय का उपयोग करना NSNotificationअधिक "स्विफ्ट 3-वाई" होगा :-)
निकोलस मारी

यदि कोई नावबार है तो इसके साथ रिपॉजिट करने में मदद मिलेगी - यदि इसके साथ UIView.animate को घेर दिया जाए तो - if let को = self.navigationController? .NavigationBar.frame {let y = फ्रेम.साइज़ .height + फ्रेम.origin.y}
सीन देव

जब रोटेशन होता है लोडिंग में गड़बड़ होती है और कुछ सेल गायब हो जाता है जब
टेबलव्यू को मेनुलली

अच्छा समाधान धन्यवाद! नोट - अब रिमूवर को हटाने की जरूरत नहीं है।
निक मैककोनेल 23

44

मुझे भी यही समस्या थी लेकिन ध्यान दिया कि यह केवल एक दृश्य में दिखाई देता है। इसलिए मैंने नियंत्रकों में अंतर खोजना शुरू किया।

मुझे पता चला कि स्क्रॉलिंग व्यवहार - (void)viewWillAppear:(BOOL)animatedसुपर इंस्टेंस में सेट है ।

तो इस तरह से लागू करना सुनिश्चित करें:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // your code
}

और इससे कोई फर्क नहीं पड़ता कि आप उपयोग करते हैं UIViewControllerया UITableViewController; UITableViewस्वयं के एक उप-क्षेत्र के रूप में डालकर इसकी जाँच की UIViewController। यह वही व्यवहार था। यदि कॉल [super viewWillAppear:animated];गायब था , तो दृश्य को स्क्रॉल करने की अनुमति नहीं थी।


1
इसने बेहतरीन काम किया। मैं सोच रहा था कि लोगों ने कहा कि यूआईटेबल व्यू मेरे लिए क्या करेगा और इसने इसे हल किया। धन्यवाद!
ओलिवारेसएफ

5
मुझे भी यह समस्या थी, इस उत्तर को ऊपर तक बना देना चाहिए!
एमिएल मार्टिन

मैं इतना समय खो गया कि इसे अपने दम पर जानने की कोशिश कर रहा था ... धन्यवाद;)
बुदीनो

+1 थोड़ा रोना शुरू कर रहा था, मेरे पास वह लाइन थी, लेकिन इसके लिए भी आवश्यक था [tableViewController viewWillAppear: animated]; क्योंकि मैं एक UIVIVController के लिए एक UITableViewController जोड़ रहा हूँ। कोई और अधिक आँसू :)
कॉलिन लैमर्रे

41

मुझे यह याद आ गया होगा, क्योंकि मैंने यहाँ पूरी पोस्ट नहीं पढ़ी, लेकिन जो मैं आया वह भ्रामक है। मैंने इसे सभी स्थितियों में परीक्षण के माध्यम से नहीं डाला है, लेकिन ऐसा लगता है कि इसे ठीक काम करना चाहिए।

बस सामग्री को समायोजित करें। कीबोर्ड की ऊंचाई के आधार पर तालिका के अंत में, और फिर सेल को नीचे तक स्क्रॉल करें:

- (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);
    self.myTableView.contentInset = contentInsets;
    self.myTableView.scrollIndicatorInsets = contentInsets;

    [self.myTableView scrollToRowAtIndexPath:self.currentField.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

और निश्चित रूप से

- (void)keyboardWasHidden:(NSNotification *)aNotification
{
    [UIView animateWithDuration:.3 animations:^(void) 
    {
        self.myTableView.contentInset = UIEdgeInsetsZero;
        self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
    }];
}

क्या यह बहुत आसान है? क्या मैं कुछ भूल रहा हूँ? अब तक यह मेरे लिए ठीक काम कर रहा है, लेकिन जैसा कि मैंने कहा, मैंने इसे रिंगर के माध्यम से नहीं डाला है ...


IMO, यह सबसे अच्छा समाधान है। केवल एक चीज जो मैं बदलूंगा वह है आपकी हार्डकोड अवधि[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
एंडी

यह बहुत ही सरल है। लेकिन एक मुद्दा मुझे लगता है कि यह परिवर्तन को चेतन नहीं करेगा contentInsetऔर स्क्रॉल सीमा को तेजी से बदल देगा।
गीक

इसने मेरे लिए सबसे अच्छा काम किया, हालाँकि, कुछ मुद्दों पर। 1) मुझे नहीं पता कि आपको "currentField.indexPath" कहां मिल सकता है, इसलिए मुझे indexPath.row को फ़ील्ड के टैग के रूप में सहेजना होगा और बाद में indexPath बनाना होगा। 2) तालिका के शीर्ष पर पंक्तियों के लिए काम नहीं करता है, यह उन्हें स्क्रीन से स्क्रॉल करता है। केवल स्क्रॉल करने के लिए कुछ कोड जोड़ने के लिए था अगर currentField का indexPath स्क्रीन पर फिट हो सकता है तो इससे अधिक है। 3) आईपैड पर kbSize.Width (ऊंचाई के बजाय) का उपयोग करना पड़ता है अगर यह लैंडस्केप है
ट्रैविस एम।

क्षमा करें, हम अपने ही कोड के इतने अभ्यस्त हो जाते हैं कि हम कभी-कभी भूल जाते हैं, एह? currentField वर्तमान पाठ क्षेत्र है, जिसके साथ मैं काम कर रहा हूं, और indexPath एक ऐसा एक्सटेंशन है, जो मैंने उस वर्ग में जोड़ा है जो केवल एक NSIndexPath जोड़ता है इसलिए मुझे पता है कि यह किस सेल में है।
mickm

यह जाने का तरीका है, सिर्फ टेबल प्रॉपर्टी को संशोधित करने के लिए फ्रेम को इधर-उधर न करना।
नेक्सर्ल

35

मुझे लगता है कि मैं ऐप्पल के ऐप के व्यवहार से मेल खाने के समाधान के साथ आया हूं।

सबसे पहले, अपने viewWillAppear में: कीबोर्ड नोटिफिकेशन को सब्सक्राइब करें, ताकि आपको पता चल जाए कि कीबोर्ड कब दिखाएगा और छिपाएगा, और सिस्टम आपको कीबोर्ड का साइज बताएगा, लेकिन डोनर 'अपने व्यूविल्डस्पेयर में अनरजिस्ट्री करना न भूलें:।

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

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

-(void) keyboardWillShow:(NSNotification *)note
{
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
    keyboardHeight = keyboardBounds.size.height;
    if (keyboardIsShowing == NO)
    {
        keyboardIsShowing = YES;
        CGRect frame = self.view.frame;
        frame.size.height -= keyboardHeight;

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:0.3f];
        self.view.frame = frame;
        [UIView commitAnimations];
    }
}

अब यहाँ स्क्रॉलिंग बिट है, हम पहले कुछ आकारों का काम करते हैं, फिर हम देखते हैं कि हम दृश्य क्षेत्र में कहाँ हैं, और जो सेट हम स्क्रॉल करना चाहते हैं, वह पाठ क्षेत्र के मध्य में ऊपर या नीचे आधा दृश्य हो सकता है। यह देखने में कहाँ पर है। इस मामले में, हमारे पास UITextFields की एक सरणी है और उनमें से एक ट्रैक रखने वाला एक एनम है, इसलिए पंक्ति संख्या द्वारा पंक्तिहाइट को गुणा करना हमें इस बाहरी दृश्य के भीतर फ्रेम की वास्तविक ऑफसेट देता है।

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect frame = textField.frame;
    CGFloat rowHeight = self.tableView.rowHeight;
    if (textField == textFields[CELL_FIELD_ONE])
    {
        frame.origin.y += rowHeight * CELL_FIELD_ONE;
    }
    else if (textField == textFields[CELL_FIELD_TWO])
    {
        frame.origin.y += rowHeight * CELL_FIELD_TWO;
    }
    else if (textField == textFields[CELL_FIELD_THREE])
    {
        frame.origin.y += rowHeight * CELL_FIELD_THREE;
    }
    else if (textField == textFields[CELL_FIELD_FOUR])
    {
        frame.origin.y += rowHeight * CELL_FIELD_FOUR;
    }
    CGFloat viewHeight = self.tableView.frame.size.height;
    CGFloat halfHeight = viewHeight / 2;
    CGFloat midpoint = frame.origin.y + (textField.frame.size.height / 2);
    if (midpoint < halfHeight)
    {
        frame.origin.y = 0;
        frame.size.height = midpoint;
    }
    else
    {
        frame.origin.y = midpoint;
        frame.size.height = midpoint;
    }
    [self.tableView scrollRectToVisible:frame animated:YES];
}

यह काफी अच्छी तरह से काम करने लगता है।


अच्छा समाधान है। इसे पोस्ट करने के लिए धन्यवाद।
एलेक्स रेनॉल्ड्स

2
UIKeyboardBoundsUserInfoKeyआईओएस 3.2 के रूप में पदावनत किया गया है। नीचे दिए गए मेरे समाधान को देखें जो सभी मौजूदा आईओएस रिलीज my 3.0 पर काम करता है। / @ iPhoneDev
Ortwin Gentz

यह जरूरत से ज्यादा जटिल था। @ user91083 का जवाब सरल था और काम करता है।
रिचर्ड ब्राइटवेल

1
इस समाधान में एक छोटी सी समस्या है। KeyboardWillShow को AFTER textFieldDidBeginEditing कहा जाता है, इसलिए जब हम किसी सेल में स्क्रॉल करना चाहते हैं, तो
टेबल व्यू

35

यदि आप उपयोग कर सकते हैं UITableViewController, तो आपको मुफ्त में कार्यक्षमता मिलती है। कभी-कभी, हालांकि, यह एक विकल्प नहीं है, खासकर अगर आपको कई विचारों की आवश्यकता है न कि सिर्फ UITableView

यहां प्रस्तुत कुछ समाधान iOS some4 पर काम नहीं करते हैं, कुछ iPad पर या लैंडस्केप मोड में काम नहीं करते हैं, कुछ ब्लूटूथ कीबोर्ड के लिए काम नहीं करते हैं (जहां हम कोई स्क्रॉल नहीं करना चाहते हैं), कुछ नहीं कई टेक्स्ट फ़ील्ड के बीच स्विच करते समय काम करें। इसलिए यदि आप कोई समाधान चुनते हैं, तो इन मामलों का परीक्षण करना सुनिश्चित करें। यह वह समाधान है जिसका उपयोग हम InAppSettingsKit में करते हैं :

- (void)_keyboardWillShow:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0
        NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"];
        if (!keyboardFrameValue) {
            keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
        }

        // Reduce the tableView height by the part of the keyboard that actually covers the tableView
        CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            windowRect = IASKCGRectSwap(windowRect);
        }
        CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
        if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
            viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
        }
        CGRect frame = _tableView.frame;
        frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute);

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = frame;
        [UIView commitAnimations];

        UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview;
        NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell];

        // iOS 3 sends hide and show notifications right after each other
        // when switching between textFields, so cancel -scrollToOldPosition requests
        [NSObject cancelPreviousPerformRequestsWithTarget:self];

        [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
}

- (void) scrollToOldPosition {
  [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)_keyboardWillHide:(NSNotification*)notification {
    if (self.navigationController.topViewController == self) {
        NSDictionary* userInfo = [notification userInfo];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
        [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
        _tableView.frame = self.view.bounds;
        [UIView commitAnimations];

        [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1];
    }
}   

यहाँ InAppSettingsKit में कक्षा का पूरा कोड है । इसका परीक्षण करने के लिए, "पूर्ण सूची" चाइल्ड पेन का उपयोग करें जहाँ आप ऊपर उल्लिखित परिदृश्यों का परीक्षण कर सकते हैं।


मुझे पता नहीं है कि यदि स्थिरांक के बजाय तार का उपयोग करना उपयोगी है, क्योंकि अगर Apple को कुछ कारणों से आंतरिक रूप से स्ट्रिंग को बदलने का विचार आता है, तो आपका समाधान अब काम नहीं कर रहा है। इसी तरह जब आपको पदावनत किया गया तो आपको चेतावनी नहीं मिली थी। मुझे लगता है

@ योग्य: यह आदर्श नहीं है, मुझे पता है। क्या आप सभी संस्करणों पर चलने वाले बेहतर समाधान का सुझाव दे सकते हैं ?3.0?
Ortwin Gentz

1
आकर्षण की तरह काम करता है, लेकिन UIInterfaceOrientationPortraitUpsideDown के लिए नहीं। फिर ऊंचाई में कमी की गणना को भी उल्टा आधारित करना पड़ता है: CGFloat कम करेंHeight = keyboardRect.size.height - (CGRectGetMinY (viewRectAbsolute) - CectectGetMinY (windowRect));
कालस

यह मेरे iPad और सिम्युलेटर (4.3) पर बहुत ध्यान देने योग्य दृश्य glitches है। उपयोग करने के लिए बहुत ध्यान देने योग्य। :(
बॉब स्प्रीन

मुझे पसंद है कि यह समाधान स्क्रीन के नीचे एक टूलबार के लिए जिम्मेदार होगा।
pdemarest 1

24

स्विफ्ट के लिए सबसे सरल उपाय :

override func viewDidLoad() {
    super.viewDidLoad()

    searchBar?.becomeFirstResponder()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillShow(_:)), name: UIKeyboardDidShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillHide(_:)), name: UIKeyboardDidHideNotification, object: nil)
}

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

func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue.size.height {
            tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    UIView.animateWithDuration(0.2, animations: { self.table_create_issue.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) })
    // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
    }

पूरी तरह से काम करता है, न्यूनतम गणना की जरूरत है। मैंने कुछ कोड जोड़े हैं जो इस उत्तर को समाप्त करने के लिए टेबल इनसेट को पुनर्स्थापित करता है।
विटाली

सबसे अच्छा समाधान धन्यवाद। मैंने यहां एक स्विफ्ट 3 संस्करण पोस्ट किया है: stackoverflow.com/a/41040630/1064438
squall2022

सुपर परफेक्ट सॉल्यूशन कभी देखा, मैंने दूसरों की कोशिश की लेकिन कुछ मुद्दे हैं। आप ios 10.2 पर सही काम करते हैं।
वांगडू लिन

8

मुझे उम्मीद है कि आप लोगों को पहले से ही उन सभी को पढ़ने का एक समाधान मिल गया था। लेकिन मैंने अपना समाधान इस प्रकार पाया। मैं उम्मीद कर रहा हूं कि आपके पास पहले से एक सेल है UITextField। इसलिए तैयारी के समय केवल पंक्ति सूचकांक को पाठ क्षेत्र के टैग में रखें।

cell.textField.tag = IndexPath.row;

नीचे के रूप में वैश्विक गुंजाइश activeTextFieldके UITextFieldसाथ एक , उदाहरण बनाएँ :

@interface EditViewController (){

    UITextField *activeTextField;

}

तो, अब आप अंत में मेरे कोड को कॉपी पेस्ट करें। और जोड़ने के लिए भी मत भूलनाUITextFieldDelegate

#pragma mark - TextField Delegation

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

    activeTextField = textField;

    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField{

    activeTextField = nil;

}

रजिस्टर कीबोर्ड notifications

#pragma mark - Keyboard Activity

- (void)registerForKeyboardNotifications

{

    [[NSNotificationCenter defaultCenter] addObserver:self

                                         selector:@selector(keyboardWasShown:)

                                             name:UIKeyboardDidShowNotification object:nil];



    [[NSNotificationCenter defaultCenter] addObserver:self

                                         selector:@selector(keyboardWillBeHidden:)

                                             name:UIKeyboardWillHideNotification object:nil];



}

कीबोर्ड संभालती है Notifications:

जब कहा जाता है UIKeyboardDidShowNotificationभेजा है।

- (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);

    [self.tableView setContentInset:contentInsets];

    [self.tableView setScrollIndicatorInsets:contentInsets];

    NSIndexPath *currentRowIndex = [NSIndexPath indexPathForRow:activeTextField.tag inSection:0];

    [self.tableView scrollToRowAtIndexPath:currentRowIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];

}

कहा जाता है जब UIKeyboardWillHideNotificationभेज दिया जाता है

- (void)keyboardWillBeHidden:(NSNotification*)aNotification

{

    UIEdgeInsets contentInsets = UIEdgeInsetsZero;

    [self.tableView setContentInset:contentInsets];

    [self.tableView setScrollIndicatorInsets:contentInsets];

}

अब एक चीज शेष है, registerForKeyboardNotificationsविधि को ViewDidLoadविधि के रूप में कॉल करें :

- (void)viewDidLoad {

    [super viewDidLoad];

    // Registering keyboard notification

    [self registerForKeyboardNotifications];

    // Your codes here...

}

आप कर रहे हैं, आशा है कि आपका textFieldsकीबोर्ड द्वारा छिपाया नहीं जाएगा।


6

कई उत्तर (विशेष रूप से Ortwin Gentz, उपयोगकर्ता 98013) और एक अन्य पोस्ट से रिक्त स्थान में संयोजन और भरना, यह पोर्ट्रेट या लैंडस्केप मोड में एक iPad पर SDK 4.3 के लिए बॉक्स से बाहर काम करेगा:

@implementation UIView (FindFirstResponder)
- (UIResponder *)findFirstResponder
{
  if (self.isFirstResponder) {        
    return self;     
  }

  for (UIView *subView in self.subviews) {
    UIResponder *firstResponder = [subView findFirstResponder];
    if (firstResponder != nil) {
      return firstResponder;
    }
  }

  return nil;
}
@end

@implementation MyViewController

- (UIResponder *)currentFirstResponder {
  return [self.view findFirstResponder];
}

- (IBAction)editingEnded:sender {
  [sender resignFirstResponder];
}

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

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  UITableViewCell *cell = (UITableViewCell*) [[textField superview] superview];
  [_tableView scrollToRowAtIndexPath:[_tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)keyboardWillShow:(NSNotification*)notification {
  if ([self currentFirstResponder] != nil) {
    NSDictionary* userInfo = [notification userInfo];

    // we don't use SDK constants here to be universally compatible with all SDKs ≥ 3.0
    NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"];
    if (!keyboardFrameValue) {
      keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
    }

    // Reduce the tableView height by the part of the keyboard that actually covers the tableView
    CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
    CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
    CGRect frame = _tableView.frame;
    if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) {
      windowRect = CGRectMake(windowRect.origin.y, windowRect.origin.x, windowRect.size.height, windowRect.size.width);
      viewRectAbsolute = CGRectMake(viewRectAbsolute.origin.y, viewRectAbsolute.origin.x, viewRectAbsolute.size.height, viewRectAbsolute.size.width);
    }
    frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    _tableView.frame = frame;
    [UIView commitAnimations];

    UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview;
    NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell];

    // iOS 3 sends hide and show notifications right after each other
    // when switching between textFields, so cancel -scrollToOldPosition requests
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    _topmostRowBeforeKeyboardWasShown = [[_tableView indexPathsForVisibleRows] objectAtIndex:0];
    [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
  }
}

- (void) scrollToOldPosition {
  [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

- (void)keyboardWillHide:(NSNotification*)notification {
  if ([self currentFirstResponder] != nil) {

    NSDictionary* userInfo = [notification userInfo];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    _tableView.frame = self.view.bounds;
    [UIView commitAnimations];

    [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1];
  }
}   

@end

मैंने iOS 4.x में इस कोड का उपयोग ठीक-ठीक किया है, लेकिन iOS5 में यह ScrollToOldPosition में क्रैश हो जाता है क्योंकि _topmostRowBeforeKeyboardWasShown उस समय पहले से ही मुक्त है। निश्चित नहीं है कि समाधान क्या है। संभवतः वस्तु के बजाय सूचकांक को याद रखें।
थॉमस टेंपेलमैन

5

यदि आप अपने टेक्स्टफ़िल्ड ( जेफ़ लामरेच से ) को रखने के लिए एक यूफ़टेव्यू का उपयोग करते हैं , तो आप बस प्रतिनिधि पद्धति का उपयोग करके टेबलव्यू को स्क्रॉल कर सकते हैं।

(नोट: मेरे पाठ फ़ील्ड को उसी अनुक्रम में सरणी में संग्रहीत किया जाता है जहां तालिका में पंक्ति होती है)

- (void) textFieldDidBeginEditing:(UITextField *)textField
    {

        int index;
        for(UITextField *aField in textFields){

            if (textField == aField){
                index = [textFields indexOfObject:aField]-1;
            }
        }

         if(index >= 0) 
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];

        [super textFieldDidBeginEditing:textField];
    }

आप टेबल व्यू फ्रेम को अपडेट नहीं करते हैं। फिर, कीबोर्ड दिखाए जाने पर स्क्रॉलबार और स्क्रॉलिंग का व्यवहार गलत है। मेरा समाधान देखें।
ऑर्टविन Gentz

5

कीबोर्ड सूचनाएँ काम करती हैं, लेकिन Apple का नमूना कोड मानता है कि स्क्रॉल दृश्य विंडो का मूल दृश्य है। यह आमतौर पर मामला नहीं है। आपको सही ऑफसेट प्राप्त करने के लिए टैब बार आदि की भरपाई करनी होगी।

यह जितना लगता है उससे कहीं ज्यादा आसान है। यहाँ एक UITableViewController में उपयोग किया गया कोड है। इसके दो इंस्टेंस वेरिएबल्स, हिडनरेक्ट और कीबोर्डशॉउन हैं।

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
    if (keyboardShown)
        return;

    NSDictionary* info = [aNotification userInfo];

    // Get the frame of the keyboard.
    NSValue *centerValue = [info objectForKey:UIKeyboardCenterEndUserInfoKey];
    NSValue *boundsValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
    CGPoint keyboardCenter = [centerValue CGPointValue];
    CGRect keyboardBounds = [boundsValue CGRectValue];
    CGPoint keyboardOrigin = CGPointMake(keyboardCenter.x - keyboardBounds.size.width / 2.0,
                                         keyboardCenter.y - keyboardBounds.size.height / 2.0);
    CGRect keyboardScreenFrame = { keyboardOrigin, keyboardBounds.size };


    // Resize the scroll view.
    UIScrollView *scrollView = (UIScrollView *) self.tableView;
    CGRect viewFrame = scrollView.frame;
    CGRect keyboardFrame = [scrollView.superview convertRect:keyboardScreenFrame fromView:nil];
    hiddenRect = CGRectIntersection(viewFrame, keyboardFrame);

    CGRect remainder, slice;
    CGRectDivide(viewFrame, &slice, &remainder, CGRectGetHeight(hiddenRect), CGRectMaxYEdge);
    scrollView.frame = remainder;

    // Scroll the active text field into view.
    CGRect textFieldRect = [/* selected cell */ frame];
    [scrollView scrollRectToVisible:textFieldRect animated:YES];

    keyboardShown = YES;
}


// Called when the UIKeyboardDidHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
    // Reset the height of the scroll view to its original value
    UIScrollView *scrollView = (UIScrollView *) self.tableView;
    CGRect viewFrame = [scrollView frame];
    scrollView.frame = CGRectUnion(viewFrame, hiddenRect);

    keyboardShown = NO;
}

UIKeyboardCenterEndUserInfoKeyऔर UIKeyboardBoundsUserInfoKeyआईओएस 3.2 के रूप में पदावनत किया जाता है। नीचे दिए गए मेरे समाधान को देखें जो सभी मौजूदा आईओएस रिलीज my 3.0 पर काम करता है।
Ortwin Gentz

5

यदि आप उपयोग करते हैं Three20, तो autoresizesForKeyboardसंपत्ति का उपयोग करें । बस अपने दृश्य नियंत्रक की -initWithNibName:bundleविधि में सेट करें

self.autoresizesForKeyboard = YES

यह ध्यान रखता है:

  1. कीबोर्ड सूचनाओं के लिए सुनना और तालिका दृश्य के फ्रेम को समायोजित करना
  2. पहले प्रत्युत्तर के लिए स्क्रॉल

किया और किया।


यहाँ तीन20 क्या है? क्या आप इसे निर्दिष्ट कर सकते हैं?
मुबीन मॉल

5

मेरा दृष्टिकोण:

मैं पहले UITextField को उप-वर्ग करता हूं और एक indexPath संपत्ति जोड़ता हूं। CellFor में ... Method मैं indexPath प्रॉपर्टी को सौंपता हूं।

फिर मैं निम्नलिखित कोड जोड़ता हूं:

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:textField.indexPath];

CGPoint cellPoint = [cell convertPoint:textField.center toView:self.tableView];
[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, cellPoint.y-50);}];

textFieldShould / WillBegin ... आदि के लिए।

जब कीबोर्ड गायब हो जाता है, तो आपको इसे उल्टा करना होगा:

[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, 0);}];

4

एक अधिक धारा-पंक्तिवाला समाधान। यह UITextField प्रतिनिधि विधियों में फिसल जाता है, इसलिए इसे w / UIKeyboard सूचनाओं को गड़बड़ करने की आवश्यकता नहीं होती है।

कार्यान्वयन नोट:

kSettingsRowHeight - एक UITableViewCell की ऊंचाई।

ऑफ़सेटगेट और ऑफ़सेटट्रेशोल्ड kSettingsRowHeight से दूर हैं। यदि आप एक अलग पंक्ति ऊंचाई का उपयोग करते हैं, तो उन मानों को बिंदु y की संपत्ति पर सेट करें। [alt: एक अलग तरीके से पंक्ति ऑफसेट की गणना करें।]

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat offsetTarget    = 113.0f; // 3rd row
CGFloat offsetThreshold = 248.0f; // 6th row (i.e. 2nd-to-last row)

CGPoint point = [self.tableView convertPoint:CGPointZero fromView:textField];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

CGRect frame = self.tableView.frame;
if (point.y > offsetThreshold) {
    self.tableView.frame = CGRectMake(0.0f,
                      offsetTarget - point.y + kSettingsRowHeight,
                      frame.size.width,
                      frame.size.height);
} else if (point.y > offsetTarget) {
    self.tableView.frame = CGRectMake(0.0f,
                      offsetTarget - point.y,
                      frame.size.width,
                      frame.size.height);
} else {
    self.tableView.frame = CGRectMake(0.0f,
                      0.0f,
                      frame.size.width,
                      frame.size.height);
}

[UIView commitAnimations];

return YES;

}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

CGRect frame = self.tableView.frame;
self.tableView.frame = CGRectMake(0.0f,
                  0.0f,
                  frame.size.width,
                  frame.size.height);

[UIView commitAnimations];

return YES;

}


4

उपयोग UITextField's delegateविधि:

तीव्र

func textFieldShouldBeginEditing(textField: UITextField) -> bool {
  let txtFieldPosition = textField.convertPoint(textField.bounds.origin, toView: yourTableViewHere)
  let indexPath = yourTablViewHere.indexPathForRowAtPoint(txtFieldPosition)
  if indexPath != nil {
     yourTablViewHere.scrollToRowAtIndexPath(indexPath!, atScrollPosition: .Top, animated: true)
  }
  return true
}

उद्देश्य सी

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
  CGPoint txtFieldPosition = [textField convertPoint:CGPointZero toView: yourTablViewHere];
  NSLog(@"Begin txtFieldPosition : %@",NSStringFromCGPoint(txtFieldPosition));
  NSIndexPath *indexPath = [yourTablViewHere indexPathForRowAtPoint:txtFieldPosition];

  if (indexPath != nil) {
     [yourTablViewHere scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
  }
  return YES;
}

नमस्ते, मैं इस मुद्दे को स्विफ्ट पर काम करने के लिए कर रहा हूँ। मेरा UITextFields UITableViewCell से जुड़ा है। यदि मैं अपने UIViewController के अंदर इस कोड को लागू करता हूं तो मेरे पास UITextFields की कोई पहुंच नहीं है। कोई विचार?
वेटुका

4

स्विफ्ट ४.२ पूरा समाधान

मैंने जीआईएसटी को प्रोटोकॉल के सेट के साथ बनाया है जो कीबोर्ड दिखाए जाने, छिपाने या बदलने पर अतिरिक्त स्थान जोड़ने के साथ काम को सरल बनाता है

विशेषताएं :

  • सही ढंग से कीबोर्ड फ्रेम में बदलाव के साथ काम करता है (उदाहरण के लिए इमोजी → सामान्य कीबोर्ड की तरह कीबोर्ड की ऊंचाई में बदलाव)।
  • UITableView उदाहरण के लिए टैबबार और टूलबार समर्थन (अन्य उदाहरणों में आप गलत इनसेट प्राप्त करते हैं)।
  • गतिशील एनीमेशन अवधि (हार्ड-कोडित नहीं)।
  • प्रोटोकॉल-उन्मुख दृष्टिकोण जो आपके उद्देश्यों के लिए आसानी से संशोधित किया जा सकता है।

प्रयोग

व्यू कंट्रोलर में बेसिक यूज़ उदाहरण जिसमें कुछ स्क्रॉल व्यू होते हैं (टेबल व्यू समर्थित है बेशक)।

class SomeViewController: UIViewController {
  @IBOutlet weak var scrollView: UIScrollView!

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

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

extension SomeViewController: ModifableInsetsOnKeyboardFrameChanges {
  var scrollViewToModify: UIScrollView { return scrollView }
}

कोर: फ्रेम ऑब्जर्वर बदलता है

प्रोटोकॉल KeyboardChangeFrameObserverहर बार कीबोर्ड के फ्रेम को बदलने (दिखाने, छिपने, फ्रेम बदलने सहित) को आग लगा देगा।

  1. या इसी तरह की विधि addKeyboardFrameChangesObserver()पर कॉल करें viewWillAppear()
  2. या इसी तरह की विधि removeKeyboardFrameChangesObserver()पर कॉल करें viewWillDisappear()

कार्यान्वयन: स्क्रॉलिंग दृश्य

ModifableInsetsOnKeyboardFrameChangesप्रोटोकॉल UIScrollViewकोर प्रोटोकॉल के लिए समर्थन जोड़ता है। कीबोर्ड के फ्रेम में बदलाव होने पर यह स्क्रॉल व्यू के इनसेट को बदल देता है।

आपकी कक्षा को स्क्रॉल दृश्य सेट करने की आवश्यकता है, कीबोर्ड के फ़्रेम परिवर्तन पर किसी के इनसेट को बढ़ाया / घटाया जाएगा।

var scrollViewToModify: UIScrollView { get }

3

चूंकि आपके पास एक तालिका में टेक्स्टफ़िल्ड है, इसलिए तालिका का आकार बदलने का सबसे अच्छा तरीका है - आपको तालिका का आकार निर्धारित करना होगा। कीबोर्ड के आकार से ऊंचाई में छोटा होना चाहिए (मुझे लगता है कि यह लगभग 165 पिक्सेल है) और फिर इसे फिर से विस्तारित करें जब कीबोर्ड को खारिज कर दिया गया है।

यदि आप उपयोगकर्ता को स्क्रॉल नहीं करना चाहते हैं, तो आप उस समय भी तालिका दृश्य के लिए उपयोगकर्ता सहभागिता को वैकल्पिक रूप से अक्षम कर सकते हैं।


मैं यह दूसरा है, और कीबोर्ड के आकार को गतिशील रूप से खोजने के लिए UIKeyboardWillShowNotification के लिए पंजीकरण करें।
बेंज़ादो

नोटिफिकेशन ऑब्जेक्ट द्वारा दिया गया नंबर हालांकि काम नहीं करता है। या कम से कम यह 2.2 में नहीं था, वापसी की संख्या गलत थी और मुझे ऊंचाई को सही ढंग से समायोजित करने के लिए 165 मानों को कठिन-कोड करना पड़ा (यह पांच से दस पिक्सल से दूर था)
केंडल हेल्मसटेटर गेलनर

2

यह पूरी तरह से काम करता है, और iPad पर भी।

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

    if(textField == textfield1){
            [accountName1TextField becomeFirstResponder];
        }else if(textField == textfield2){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield3 becomeFirstResponder];

        }else if(textField == textfield3){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield4 becomeFirstResponder];

        }else if(textField == textfield4){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield5 becomeFirstResponder];

        }else if(textField == textfield5){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield6 becomeFirstResponder];

        }else if(textField == textfield6){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield7 becomeFirstResponder];

        }else if(textField == textfield7){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield8 becomeFirstResponder];

        }else if(textField == textfield8){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textfield9 becomeFirstResponder];

        }else if(textField == textfield9){
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:7 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
            [textField resignFirstResponder];
        }

आप प्रत्येक टेक्स्टफ़ील्ड के लिए विशेष मामलों का उपयोग क्यों कर रहे हैं? सेल के NSIndexPath से प्रत्येक टेक्स्टफील्ड को आईडी करें और कोड के 2 लाइनों में स्टेटमेंट होने पर उस नॉटी को बदल दें। आप वास्तव में एक cellForRowAtIndexPath कॉल चाहते हैं और फिर सेल से टेक्स्टफिल्ड प्राप्त करें।
एलेक्स ज़ावाटोन

वास्तव में यह देखते हुए कि आईओएस पर यह स्थिति कितनी अविश्वसनीय है, मुझे लगता है कि इस स्थिति के लिए "पूरी तरह से अनावश्यक, हास्यास्पद शाब्दिक" कोड लिखना ठीक है।
फेटी

इस जवाब को ध्यान में रखते हुए 6 साल पहले दिया गया था।
राइट्ससीएस

2

मैंने लगभग उसी दृष्टिकोण की कोशिश की और उसी के लिए एक सरल और छोटे कोड के साथ आया। मैंने एक IBOutlet iTextView बनाया और IB में UITextView से जुड़ा।

 -(void)keyboardWillShow:(NSNotification *)notification
    {
        NSLog(@"Keyboard");
        CGRect keyFrame = [[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];

        [UIView beginAnimations:@"resize view" context:nil];
        [UIView setAnimationCurve:1];
        [UIView setAnimationDuration:1.0];
        CGRect frame = iTableView.frame;
        frame.size.height = frame.size.height -  keyFrame.size.height;
        iTableView.frame = frame;
        [iTableView scrollRectToVisible:frame animated:YES];
        [UIView commitAnimations];

    }

2

इसलिए इन वर्तमान समाधानों (और पूरी तरह से विफल) का उपयोग करने की कोशिश कर रहे घंटों के भीषण काम के बाद, मुझे अंततः अच्छी तरह से काम करने की चीजें मिलीं, और उन्हें नए एनीमेशन ब्लॉकों का उपयोग करने के लिए अद्यतन किया। मेरा जवाब पूरी तरह से ऊपर दिए गए Ortwin के जवाब पर आधारित है

तो जो भी कारण के लिए ऊपर कोड सिर्फ मेरे लिए काम नहीं कर रहा था। मेरा सेटअप काफी हद तक दूसरों के समान था, लेकिन शायद इसलिए कि मैं iPad या 4.3 पर था ... कोई विचार नहीं। यह कुछ निराला गणित कर रहा था और स्क्रीन से मेरे टेबलव्यू की शूटिंग कर रहा था।

मेरे समाधान का अंतिम परिणाम देखें: http://screencast.com/t/hjBCuRrPC (कृपया फोटो को नजरअंदाज करें। :-P)

इसलिए मैं ऑर्टविन जो कर रहा था, उसके साथ चला गया, लेकिन यह बदल गया कि कीबोर्ड की ऊंचाई के साथ मेरे टेबल व्यू के मूल .y और size.height को जोड़ने के लिए कुछ गणित कैसे कर रहा था। जब मैं उस परिणाम से खिड़की की ऊंचाई घटाता हूं, तो यह बताता है कि मेरे पास कितना चौराहा है। यदि इसका 0 से अधिक (उर्फ कुछ ओवरलैप है) तो मैं फ्रेम ऊंचाई का एनीमेशन करता हूं।

इसके अलावा कुछ redraw के मुद्दे थे जो 1 द्वारा हल किए गए थे) सेल को स्क्रॉल करने का इंतजार जब तक एनीमेशन नहीं किया गया और 2) कीबोर्ड को छुपाते समय UIViewAnimationOptionBeginFromCurrentState विकल्प का उपयोग किया गया।

एक दो बातें ध्यान दें।

  • _topmostRowBeforeKeyboardWasShown और _originalFrame हेडर में घोषित उदाहरण चर हैं।
  • self.guestEntryTableView मेरा टेबल व्यू है (मैं एक बाहरी फ़ाइल में हूं)
  • IASKCGRectSwap एक फ्रेम के निर्देशांक को फ़्लिप करने के लिए ऑर्टविन की विधि है
  • मैं केवल तालिका दृश्य की ऊँचाई को अद्यतन करता हूँ यदि इसमें से कम से कम 50px दिखाई देने वाला है
  • चूंकि मैं एक UIViewController में नहीं हूं, इसलिए मेरे पास self.view नहीं है, इसलिए मैं सिर्फ टेबल व्यू को उसके मूल फ्रेम में लौटाता हूं

यदि मैं ऑर्टविन ने इसका क्रैड प्रदान नहीं किया तो फिर से, मैं इस उत्तर के पास नहीं पहुँचूँगा। यहाँ कोड है:

- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeTextField = textField;

    if ([self.guestEntryTableView indexPathsForVisibleRows].count) {
        _topmostRowBeforeKeyboardWasShown = (NSIndexPath*)[[self.guestEntryTableView indexPathsForVisibleRows] objectAtIndex:0];
    } else {
        // this should never happen
        _topmostRowBeforeKeyboardWasShown = [NSIndexPath indexPathForRow:0 inSection:0];
        [textField resignFirstResponder];
    }
}

- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
    self.activeTextField = nil;
}

- (void)keyboardWillShow:(NSNotification*)notification {
    NSDictionary* userInfo = [notification userInfo];

    NSValue* keyboardFrameValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    // Reduce the tableView height by the part of the keyboard that actually covers the tableView
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
    CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
    CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
    if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation ) {
        windowRect = IASKCGRectSwap(windowRect);
        viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
        keyboardFrame = IASKCGRectSwap(keyboardFrame);
    }

    // fix the coordinates of our rect to have a top left origin 0,0
    viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);

    CGRect frame = self.guestEntryTableView.frame;
    _originalFrame = self.guestEntryTableView.frame;

    int remainder = (viewRectAbsolute.origin.y + viewRectAbsolute.size.height + keyboardFrame.size.height) - windowRect.size.height;

    if (remainder > 0 && !(remainder > frame.size.height + 50)) {
        frame.size.height = frame.size.height - remainder;
        float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        [UIView animateWithDuration: duration
                        animations:^{
                            self.guestEntryTableView.frame = frame;
                        }
                        completion:^(BOOL finished){
                            UITableViewCell *textFieldCell = (UITableViewCell*) [[self.activeTextField superview] superview];
                            NSIndexPath *textFieldIndexPath = [self.guestEntryTableView indexPathForCell:textFieldCell];
                            [self.guestEntryTableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
                        }];
    }

}

- (void)keyboardWillHide:(NSNotification*)notification {
    NSDictionary* userInfo = [notification userInfo];
    float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    [UIView animateWithDuration: duration
                          delay: 0.0
                        options: (UIViewAnimationOptionBeginFromCurrentState)
                     animations:^{
                         self.guestEntryTableView.frame = _originalFrame;
                     }
                     completion:^(BOOL finished){
                         [self.guestEntryTableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
                     }];

}   

#pragma mark CGRect Utility function
CGRect IASKCGRectSwap(CGRect rect) {
    CGRect newRect;
    newRect.origin.x = rect.origin.y;
    newRect.origin.y = rect.origin.x;
    newRect.size.width = rect.size.height;
    newRect.size.height = rect.size.width;
    return newRect;
}

CGRect FixOriginRotation(CGRect rect, UIInterfaceOrientation orientation, int parentWidth, int parentHeight) {
    CGRect newRect;
    switch(orientation)
    {
        case UIInterfaceOrientationLandscapeLeft:
            newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), rect.origin.y, rect.size.width, rect.size.height);
            break;
        case UIInterfaceOrientationLandscapeRight:
            newRect = CGRectMake(rect.origin.x, parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
            break;
        case UIInterfaceOrientationPortrait:
            newRect = rect;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
            break;
    }
    return newRect;
}

मेरे FixOriginRotation फ़ंक्शन को जोड़ा गया है जो दृश्य के समन्वय प्रणाली को ठीक करता है इससे पहले कि आप इसके फ्रेम को अपडेट करें आदि। मुझे लगता है कि यह इस बात का हिस्सा है कि मुझे पहले क्यों परेशानी हो रही थी। डिवाइस के साथ घुमाया गया iOS विंडो कोऑर्डिनेट सिस्टम की जानकारी नहीं थी!
बॉब स्प्रीन

2

यह विलेन मेरे लिए काम करता है, कृपया रेखा पर ध्यान दें

[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];

आप इसे अपने साथ काम करने के लिए 160 मान बदल सकते हैं

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = activeField.superview.frame;
                        bkgndRect.size.height += kbSize.height;
     [activeField.superview setFrame:bkgndRect];
     [tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
   activeField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
 {
     activeField = nil;
 }
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    tableView.contentInset = contentInsets;
    tableView.scrollIndicatorInsets = contentInsets;
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect = activeField.superview.frame;
    //bkgndRect.size.height += kbSize.height;
    [activeField.superview setFrame:bkgndRect];
    [tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}

2

बहुत दिलचस्प चर्चा सूत्र, मैं भी एक ही समस्या का सामना करना पड़ा क्योंकि एक बदतर हो सकता है

  1. मैं एक कस्टम सेल का उपयोग कर रहा था और टेक्स्टफील्ड उसी के अंदर था।
  2. मुझे अपनी आवश्यकताओं को पूरा करने के लिए UIViewController का उपयोग करना था इसलिए कठबोली UITableViewController का लाभ उठा सकती है।
  3. मेरे टेबल सेल में फ़िल्टर / सॉर्ट मानदंड थे, यानी यूआर सेल इंडेक्सपथ का ट्रैक बदलते रहते हैं और सभी मदद नहीं करेंगे।

इसलिए यहां थ्रेड्स पढ़ें और मेरे संस्करण को लागू किया, जिसने मुझे आईपैड को लैंडस्केप मोड में अपनी सामग्री को आगे बढ़ाने में मदद की । यहाँ कोड है (यह मूर्ख प्रमाण नहीं है और सभी, लेकिन इसने मेरा मुद्दा ठीक कर दिया है) सबसे पहले आपको अपने कस्टम सेल वर्ग में एक प्रतिनिधि की आवश्यकता है, जो संपादन शुरू होने पर, टेक्स्टफील्ड को उर व्यूकंट्रोलर में भेजता है और सक्रिय क्षेत्र = theTextFor को सेट करता है

// केवल लांडेस्कैप मोड को लागू करना

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect aRect = myTable.frame;

    CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);

    aRect.size.height -= kbSize.height+50;
// This will the exact rect in which your textfield is present
        CGRect rect =  [myTable convertRect:activeField.bounds fromView:activeField];
// Scroll up only if required
    if (!CGRectContainsPoint(aRect, rect.origin) ) {


            [myTable setContentOffset:CGPointMake(0.0, rect.origin.y) animated:YES];

    }


}

// जब UIKeyboardWillHideNotification भेजा गया है

- (void)keyboardWillHide:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    myTable.contentInset = contentInsets;
    myTable.scrollIndicatorInsets = contentInsets;
    NSDictionary* info = [aNotification userInfo];
    CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);
    CGRect bkgndRect = activeField.superview.frame;
    bkgndRect.size.height += kbSize.height;
    [activeField.superview setFrame:bkgndRect];
    [myTable setContentOffset:CGPointMake(0.0, 10.0) animated:YES];
}

-anoop4real


2

Google और स्टैक ओवरफ़्लो के माध्यम से पाए गए समाधानों के एक बड़े हिस्से को संदर्भित करने के बाद मैंने अपने आप से इस तरह की समस्या को हल किया है।

सबसे पहले, कृपया आश्वस्त करें कि आपने अपने UIScrollView का एक IBOutlet सेट किया है, फिर कृपया Apple Doc: कीबोर्ड प्रबंधन पर एक नज़र डालें । अंत में, यदि आप पृष्ठभूमि को स्क्रॉल कर सकते हैं, लेकिन कीबोर्ड अभी भी टेक्स्ट फ़ील्ड को कवर करता है, तो कृपया इस कोड के टुकड़े पर एक नज़र डालें:

// 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 (aRect.size.height < activeField.frame.origin.y+activeField.frame.size.height) {

    CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y+activeField.frame.size.height-aRect.size.height);

    [scrollView setContentOffset:scrollPoint animated:YES];

इस हालत में एप्पल और इस झूठ के बीच मुख्य अंतर है। मेरा मानना ​​है कि ऐप्पल की स्क्रॉल दूरी और गणना से यह पता चलता है कि क्या कीबोर्ड द्वारा कवर किया गया टेक्स्ट फील्ड सटीक नहीं है, इसलिए मैंने ऊपर जैसा ही संशोधन किया।

मुझे पता है अगर यह काम करता है


2

स्विफ्ट के साथ UITableField में UITextField के Get indexPath से टेक्स्ट फ़ील्ड के सटीक बिंदु का उपयोग करते हुए, स्विफ्ट में एक उदाहरण :

func textFieldDidBeginEditing(textField: UITextField) {
    let pointInTable = textField.convertPoint(textField.bounds.origin, toView: self.accountsTableView)
    let textFieldIndexPath = self.accountsTableView.indexPathForRowAtPoint(pointInTable)
    accountsTableView.scrollToRowAtIndexPath(textFieldIndexPath!, atScrollPosition: .Top, animated: true)
}

1

एक और आसान तरीका (केवल एक सेक्शन के साथ काम करता है)

//cellForRowAtIndexPath
UItextField *tf;
[cell addSubview:tf];
tf.tag = indexPath.row;
tf.delegate = self;

//textFieldDidBeginEditing:(UITextField *)text
[[self.tableView scrollToRowsAtIndexPath:[NSIndexPath indexPathForRow:text.tag in section:SECTIONINTEGER] animated:YES];

1

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

एक अच्छे उदाहरण के लिए Apple उदाहरण कोड प्रोजेक्ट देखें: TaggedLocations।

आप देख सकते हैं कि यह अपने आप स्क्रॉल हो जाता है, लेकिन ऐसा करने वाला कोई कोड प्रतीत नहीं होता है। इस परियोजना में कस्टम टेबल व्यू सेल भी हैं, इसलिए यदि आप एक गाइड के रूप में इसके साथ अपने आवेदन का निर्माण करते हैं, तो आपको वांछित परिणाम प्राप्त करना चाहिए।


1

यहाँ बताया गया है कि मैंने यह काम कैसे किया, जो सैम हो और मार्सेल डब्ल्यू के उत्तरों का मिश्रण है, और मेरे कुछ गंदे सुधार मेरे भद्दे कोड के लिए किए गए हैं। मैं एक UITableViewController का उपयोग कर रहा था। जब कीबोर्ड दिखाया जाता है तो तालिका अब सही ढंग से आकार देती है।

1) viewDidLoadमैंने जोड़ा:

self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

2) मैं फोन करने के लिए भूल गया था superमें समकक्ष viewWillAppearऔर awakeFromNib। मैंने इनको वापस जोड़ा।


1

UITableViewControllerस्क्रॉलिंग स्वचालित रूप से करता है, वास्तव में। UIViewControllerA का उपयोग करने की तुलना में अंतर , यह है कि आपको एक का उपयोग करते समय NavigationController, प्रोग्राम का उपयोग करके Navbar-Buttonitems बनाना होगा TableViewController

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.