Textfields (अगला / पूर्ण बटन) के माध्यम से नेविगेट कैसे करें


487

मैं iPhone कीबोर्ड पर "अगला" बटन के साथ अपने सभी पाठ क्षेत्रों के माध्यम से कैसे नेविगेट कर सकता हूं?

अंतिम पाठ फ़ील्ड को कीबोर्ड बंद करना चाहिए।

मैंने IB बटन (अगला / पूर्ण) सेटअप किया है, लेकिन अब मैं अटक गया हूं।

मैंने textFieldShouldReturn एक्शन लागू किया लेकिन अब नेक्स्ट एंड डन बटन कीबोर्ड को बंद कर देता है।


कृपया नीचे मेरे उत्तर पर एक नज़र डालें। मेरे अनुभव में यह आम तौर पर दिए गए उत्तर की तुलना में एक बेहतर, अधिक पूर्ण, समाधान है। मुझे नहीं पता कि कोई भी इसे नकारात्मक रेटिंग क्यों देगा।
मेमोन्स

मेरे पास समान मुद्दा है लेकिन कॉर्डोवा के साथ, फोनगैप क्या इसे हल करने का कोई तरीका है?

जवाबों:


578

मैक ओएस एक्स के लिए कोको में, आपके पास अगली उत्तरदाता श्रृंखला है, जहां आप पाठ क्षेत्र से पूछ सकते हैं कि नियंत्रण को आगे क्या ध्यान केंद्रित करना चाहिए। यह वह है जो टेक्स्ट फ़ील्ड के बीच तालमेल बिठाता है। लेकिन चूंकि iOS उपकरणों में कीबोर्ड नहीं होता है, केवल स्पर्श होता है, इसलिए यह अवधारणा कोको टच में संक्रमण से नहीं बची है।

यह आसानी से दो मान्यताओं के साथ किया जा सकता है:

  1. सभी "tabbable" UITextFieldएक ही मूल दृश्य पर हैं।
  2. उनका "टैब-ऑर्डर" टैग संपत्ति द्वारा परिभाषित किया गया है।

यह मानते हुए कि आप टेक्स्ट को हटा सकते हैं।

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{
  NSInteger nextTag = textField.tag + 1;
  // Try to find next responder
  UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
  if (nextResponder) {
    // Found next responder, so set it.
    [nextResponder becomeFirstResponder];
  } else {
    // Not found, so remove keyboard.
    [textField resignFirstResponder];
  }
  return NO; // We do not want UITextField to insert line-breaks.
}

कुछ और कोड जोड़ें, और मान्यताओं को भी अनदेखा किया जा सकता है।

स्विफ्ट 4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let nextTag = textField.tag + 1
    // Try to find next responder
    let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!

    if nextResponder != nil {
        // Found next responder, so set it
        nextResponder?.becomeFirstResponder()
    } else {
        // Not found, so remove keyboard
        textField.resignFirstResponder()
    }

    return false
}

यदि पाठ क्षेत्र का पर्यवेक्षक UITableViewCell होगा तो अगला उत्तरदाता होगा

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!

6
कभी-कभी कीबोर्ड के शीर्ष पर "अगला" और "पिछले" बटन होते हैं। कम से कम ब्राउज़र में।
तैमूर

31
सिर्फ पांडित्यपूर्ण होने के लिए, मैं इस पोस्ट में कुछ गलत जानकारी को साफ करना चाहता हूं। OS X पर, टैब ऑर्डर NSView के सेटNextKeyView के माध्यम से सेट किया गया है: (setNextResponder :) विधि नहीं। रेस्पोंडर श्रृंखला इससे अलग है: यह रेस्पोंडर ऑब्जेक्ट्स का एक पदानुक्रम है जो "अलक्षित" क्रियाओं को संभालता है, उदाहरण के लिए एक्शन ऑब्जेक्ट पर सीधे बजाय इसके बजाय पहले रिस्पॉन्डर को भेजे गए एक्शन। उत्तरदाता श्रृंखला आमतौर पर दृश्य पदानुक्रम का अनुसरण करती है, खिड़की और उसके नियंत्रक तक, और फिर ऐप प्रतिनिधि। बहुत सारी जानकारी के लिए Google "उत्तरदाता श्रृंखला"।
डेवहाइडेन

पाठ क्षेत्र का पर्यवेक्षक a होगा UITableViewCell। आपको संबंधित एक्सेस करने UITableViewऔर उस सेल को प्राप्त करने की आवश्यकता होगी जिसमें वह टेक्स्ट फ़ील्ड है जिसे आप खोज रहे हैं।
बजे माइकल माइर

13
UITextFieldDelegateटेक्स्टफिल्ड प्रतिनिधियों को जोड़ने और सेट करने के लिए मत भूलना ।
साल

1
स्टोरीबोर्ड (मेरे मामले में) से TAG विकल्प सेट करने के लिए अनुकूल अनुस्मारक। आपको आरोही क्रम में TextFields टैग को मैन्युअल रूप से सेट करना होगा। (इस समाधान के लिए काम करने के लिए पहला है 0, दूसरा 1 है)।
जोकिम

170

एक और अधिक सुंदर समाधान है जिसने मुझे पहली बार देखा था। लाभ:

  • OSX टेक्स्टफील्ड कार्यान्वयन के करीब जहां एक टेक्स्टफील्ड जानता है कि फोकस को आगे कहां जाना चाहिए
  • टैग सेट करने या उपयोग करने पर निर्भर नहीं करता है - जो हैं, इस उपयोग के मामले के लिए IMO नाजुक
  • दोनों UITextFieldऔर UITextViewनियंत्रण के साथ काम करने के लिए बढ़ाया जा सकता है - या कोई भी कीबोर्ड प्रविष्टि UI नियंत्रण
  • बॉयलरप्लेट UITextField प्रतिनिधि कोड के साथ अपने दृश्य नियंत्रक को अव्यवस्थित नहीं करता है
  • आईबी के साथ अच्छी तरह से एकीकृत करता है और आउटलेट्स को जोड़ने के लिए परिचित विकल्प-ड्रैग-ड्रॉप के माध्यम से कॉन्फ़िगर किया जा सकता है।

एक UITextField उपवर्ग बनाएँ जिसमें एक IBOutletसंपत्ति है जिसे NextField कहा जाता है। यहाँ हैडर है:

@interface SOTextField : UITextField

@property (weak, nonatomic) IBOutlet UITextField *nextField; 

@end

और यहाँ कार्यान्वयन है:

@implementation SOTextField

@end

आपके विचार नियंत्रक में, आप -textFieldShouldReturn:प्रतिनिधि विधि बनाएँगे :

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if ([textField isKindOfClass:[SOTextField class]]) {
        UITextField *nextField = [(SOTextField *)textField nextField];

        if (nextField) {
            dispatch_async(dispatch_get_current_queue(), ^{
                [nextField becomeFirstResponder];
            });
        }
        else {
            [textField resignFirstResponder];
        }
    }

    return YES;
}

IB में, SOTextFieldक्लास का उपयोग करने के लिए अपने UITextFields को बदलें । अगला, आईबी में भी, प्रत्येक 'SOTextFields'to' फ़ाइल का स्वामी 'के लिए प्रतिनिधि को सेट करें (जो कि वहीं है जहाँ आप प्रतिनिधि विधि के लिए कोड डालते हैं - textFieldShouldReturn)। इस डिज़ाइन की खूबी यह है कि अब आप किसी भी टेक्स्टफिल्ड पर राइट-क्लिक कर सकते हैं और अगले SOTextFieldऑब्जेक्ट के लिए अगला फ़्लिप आउटलेट असाइन कर सकते हैं जिसे आप अगला उत्तरदाता बनना चाहते हैं।

IB में अगलाField असाइन करना

इसके अलावा, आप टेक्स्ट फील्‍ड्स जैसी ठंडी चीजें कर सकते हैं ताकि अंतिम एक के बाद फोकस खो जाए, पहले वाला फोकस फिर से प्राप्त होगा।

यह आसानी से बढ़ाया जा सकता है अगर किसी नेक्स्टफिल्ड असाइन किया गया है, तो एक स्वचालित रूप से असाइन करने returnKeyTypeके लिए - एक कम चीज मैन्युअल रूप से कॉन्फ़िगर करें।SOTextFieldUIReturnKeyNext


3
मुझे वास्तव में टैग का उपयोग करने पर आईबी एकीकरण पसंद है - विशेष रूप से एक्सकोड के नए संस्करणों के साथ जो आईबी को बाकी आईडीई के साथ अच्छी तरह से एकीकृत करता है - और बॉयलरप्लेट टेक्स्टफिल्ड प्रतिनिधि कोड के साथ मेरे नियंत्रक को अव्यवस्थित करने के लिए नहीं एक बोनस है।
मेमोरियल जूल

4
टैग आसान हैं, लेकिन इस तरह से बेहतर है, और एक अच्छा ओओ डिजाइन के लिए अधिक उपयुक्त है
ब्रेन २२ डी १४'११

1
मैं वास्तव में इस समाधान को पसंद करता हूं, लेकिन मैं अलग-अलग सेल विचारों में प्रत्येक पाठ क्षेत्र का उपयोग कर रहा हूं UITableView। यद्यपि मेरे पास IBOutletप्रत्येक पाठ क्षेत्र के लिए दृश्य नियंत्रक पर गुण हैं, यह मुझे nextFieldफ़ाइल के स्वामी पर उन संपत्तियों को लिंक करने की अनुमति नहीं दे रहा है । किसी भी सलाह मैं कैसे इस परिदृश्य में काम कर सकते हैं?
जय इमरान

1
@ जयइरमैन आईबी आपको कोशिकाओं के बीच आउटलेट कनेक्ट करने की अनुमति नहीं देगा। तो, आईबी इस परिदृश्य के लिए एक नहीं जाना होगा। हालाँकि, आप कोड का उपयोग करके अगली अगली संपत्तियों को हुक कर सकते हैं। textField1.nextField = textField2; textField2.nextField = textField3;, आदि
मेमन

2
किसी भी मौका इस जवाब को नए संस्करणों के लिए अद्यतन किया जा सकता है xcode और ios?
हारीट्रेन्स्लैशन

82

यहाँ एक प्रतिनिधिमंडल के बिना है:

tf1.addTarget(tf2, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)
tf2.addTarget(tf3, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)

ObjC:

[tf1 addTarget:tf2 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
[tf2 addTarget:tf3 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];

(अधिकतर अज्ञात) UIControlEventEditingDidEndOnExit UITextFieldक्रिया का उपयोग करके काम करता है।

आप इसे आसानी से स्टोरीबोर्ड में हुक कर सकते हैं, इसलिए किसी भी प्रतिनिधिमंडल या कोड की आवश्यकता नहीं है।

संपादित करें: वास्तव में मैं यह पता नहीं लगा सकता कि इसे स्टोरीबोर्ड में कैसे हुक किया जाए। becomeFirstResponderइस नियंत्रण-ईवेंट के लिए एक प्रस्तावित कार्रवाई प्रतीत नहीं होती है, जो एक अफ़सोस की बात है। फिर भी, आप अपने ViewController में एक कार्रवाई के लिए अपने सभी textfields हुक कर सकते हैं जो तब यह निर्धारित करता है becomeFirstResponderकि प्रेषक के आधार पर कौन सा टेक्स्टफिल्ड (हालांकि तब यह उपरोक्त प्रोग्रामर समाधान के रूप में सुरुचिपूर्ण नहीं है इसलिए IMO उपरोक्त कोड के साथ ऐसा करते हैं viewDidLoad)।


18
बहुत सरल और प्रभावी उपाय। श्रृंखला में अंतिम एक भी उदाहरण के लिए ट्रिगर कर सकता है [tfN addTarget:self action:@selector(loginButtonTapped:) forControlEvents:UIControlEventEditingDidEndOnExit];। धन्यवाद @mxcl
१.२२२ बजे --२१/

आप स्टोरीबोर्ड में यह कैसे करेंगे?
पेड्रो बोर्गेस

यह शायद यहाँ सबसे अच्छा जवाब है।
daspianist

यह मेरे लिए स्विफ्ट 2 में भी पूरी तरह से काम करता है। प्रतिनिधियों में जोड़ने की तुलना में यह बहुत सरल और तेज समाधान है।
टन

2
स्विफ्ट 4: txtFirstname.addTarget (txtLastname, action: #selector (बनने के लिए फ़्रीस्ट्रेन्डर), इसके लिए: UIControlEvents.editingDidEndOnExitit
realtimez

78

यहाँ इस समस्या के लिए मेरा समाधान है।

इसे हल करने के लिए (और क्योंकि मुझे सामान करने के लिए टैग पर भरोसा करने से नफरत है) मैंने UITextField ऑब्जेक्ट में एक कस्टम गुण जोड़ने का फैसला किया। दूसरे शब्दों में मैंने इस तरह UITextField पर एक श्रेणी बनाई:

UITextField + Extended.h

@interface UITextField (Extended)

@property(retain, nonatomic)UITextField* nextTextField;

@end

UITextField + Extended.m

#import "UITextField+Extended.h"
#import <objc/runtime.h>

static char defaultHashKey;

@implementation UITextField (Extended)

- (UITextField*) nextTextField { 
    return objc_getAssociatedObject(self, &defaultHashKey); 
}

- (void) setNextTextField:(UITextField *)nextTextField{
    objc_setAssociatedObject(self, &defaultHashKey, nextTextField, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

@end

अब, यहाँ है कि मैं इसका उपयोग कैसे करूँ:

UITextField *textField1 = ...init your textfield
UITextField *textField2 = ...init your textfield
UITextField *textField3 = ...init your textfield

textField1.nextTextField = textField2;
textField2.nextTextField = textField3;
textField3.nextTextField = nil;

और textFieldShouldReturn विधि को लागू करें:

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

    UITextField *next = theTextField.nextTextField;
    if (next) {
        [next becomeFirstResponder];
    } else {
        [theTextField resignFirstResponder];
    }

    return NO; 
}

अब मेरे पास UITextField की एक लिंक की गई सूची है, हर एक को पता है कि लाइन में अगला कौन है।

आशा है कि यह मदद करेगा।


11
यह सबसे अच्छा समाधान है और इसे उत्तर के रूप में चुना जाना चाहिए।
जियोवानी

4
इस समाधान ने मेरे लिए काम किया, केवल एक चीज जिसे मैंने बदला था वह अगली टेक्स्टफिल्ड और आईबूटलेट बना रही थी ताकि मैं अपने स्टोरीबोर्ड के भीतर से चिनिंग सेट कर सकूं।
zachzurn

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

1
ध्यान दें कि यदि आईबी आपकी चीज है, तो आप इन गुणों को IBOutlets के रूप में भी सेट कर सकते हैं। । नाम टकराव से सावधान रहें - Apple अंततः इसे UIResponder में जोड़ सकता है।
जैस्पर ब्लूज

क्या यह समाधान इंटरफ़ेस बिल्डर के साथ संगत है? मेरा मतलब है कि यह IBOutlets और स्टोरीबोर्ड संदर्भों का उपयोग कर सकता है बजाय इसके कि अगलेTextField प्रोग्रामेटिक रूप से सेट करें? IB आपको किसी श्रेणी में UITextField वर्ग सेट करने की अनुमति नहीं देता है।
पेड्रो बोर्गेस

46

एक स्विफ्ट एक्सटेंशन जो कि विशेष रूप से आसान बनाने के लिए mxcl के उत्तर पर लागू होता है (यात्री द्वारा स्विफ्ट 2.3 के लिए अनुकूलित)

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for i in 0 ..< fields.count - 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), forControlEvents: .EditingDidEndOnExit)
    }
}

इसका उपयोग करना आसान है:

UITextField.connectFields([field1, field2, field3])

एक्सटेंशन सभी फ़ील्ड के लिए "अगला" पर अंतिम बटन और अंतिम फ़ील्ड के लिए "पूर्ण" करने के लिए वापसी बटन सेट करेगा, और जब ये टैप किए जाएंगे तो फ़ोकस को हटा दें / फ़ोकस को हटा दें।

स्विफ्ट <2.3

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for var i = 0; i < fields.count - 1; i += 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: "resignFirstResponder", forControlEvents: .EditingDidEndOnExit)
    }
}

स्विफ्ट 3: इस तरह का उपयोग करें -

UITextField.connectFields(fields: [field1, field2])

Extension:
    extension UITextField {
        class func connectFields(fields:[UITextField]) -> Void {
            guard let last = fields.last else {
                return
            }
            for i in 0 ..< fields.count - 1 {
                fields[i].returnKeyType = .next
                fields[i].addTarget(fields[i+1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)
            }
            last.returnKeyType = .go
            last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)
        }
    }

5
BTW, यदि आप करना चाहते हैं तो एक कार्रवाई की है, आप सिर्फ अपने देखें नियंत्रक के अनुरूप है UITextFieldDelegate, और लागू कर सकते हैं func textFieldDidEndEditing(textField: UITextField)। बस जल्दी बाहर लौटें तो textField != field3
रयान

25

NextResponderTextField का उपयोग करने के लिए एक अधिक सुसंगत और मजबूत तरीका है आप प्रतिनिधि या सेटिंग का उपयोग करने की आवश्यकता के बिना इंटरफ़ेस बिल्डर से इसे पूरी तरह से कॉन्फ़िगर कर सकते हैं view.tag

आपको बस इतना करना है

  1. अपने UITextFieldहोने का वर्ग प्रकार निर्धारित करेंNextResponderTextField यहाँ छवि विवरण दर्ज करें
  2. फिर nextResponderFieldअगले उत्तरदाता को इंगित करने के लिए आउटलेट सेट करें यह कुछ भी UITextFieldया किसी भी UIResponderउपवर्ग हो सकता है । यह एक UIButton भी हो सकता है और लाइब्रेरी TouchUpInsideबटन के ईवेंट को ट्रिगर करने के लिए पर्याप्त स्मार्ट है यदि यह सक्षम है। यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

यहाँ पुस्तकालय कार्रवाई में है:

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


हाँ। स्विफ्ट 3.1 के साथ वास्तव में अच्छी तरह से काम करता है, बहुत ही सुरुचिपूर्ण समाधान, बस आईबी कैसे बॉक्स से बाहर काम करना चाहिए।
रिचर्ड

क्षमा करें, मुझे प्रश्न नहीं मिला।
mohamede1945

1
NextResponderTextField ने मेरे लिए काम किया। यह त्वरित और प्रयोग करने में आसान था, बस एक स्विफ्ट फ़ाइल, और बिल्कुल वही किया, जिसकी मुझे कोई ज़रूरत नहीं थी।
पैट मैक

यह महान काम करता है! नोट: मुझे उदाहरण के लिए "अगला" और "पूर्ण" प्रदर्शित करने के लिए इसे प्राप्त करने के लिए मैन्युअल रूप से रिटर्न कुंजी को बदलना होगा।
माइक मिलर

14

मुझे ओओ समाधान पसंद हैं जो पहले से ही एंथ0 और उत्तरपट्टी द्वारा सुझाए गए हैं। हालांकि, मैं एक त्वरित और छोटे पीओसी पर काम कर रहा था, इसलिए मैं उपवर्गों और श्रेणियों के साथ चीजों को अव्यवस्थित नहीं करना चाहता था।

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

यहां मेरा कोड है (इस थ्रेड में अन्य उत्तरों पर निर्मित):

@property (nonatomic) NSArray *fieldArray;

- (void)viewDidLoad {
    [super viewDidLoad];

    fieldArray = [NSArray arrayWithObjects: firstField, secondField, thirdField, nil];
}

- (BOOL) textFieldShouldReturn:(UITextField *) textField {
    BOOL didResign = [textField resignFirstResponder];
    if (!didResign) return NO;

    NSUInteger index = [self.fieldArray indexOfObject:textField];
    if (index == NSNotFound || index + 1 == fieldArray.count) return NO;

    id nextField = [fieldArray objectAtIndex:index + 1];
    activeField = nextField;
    [nextField becomeFirstResponder];

    return NO;
}
  • मैं हमेशा NO लौटाता हूं क्योंकि मैं एक लाइन ब्रेक नहीं डालना चाहता हूं। बस मैंने सोचा था कि जब से मैं वापस आया था, तब से यह स्वचालित रूप से बाद के खेतों से बाहर निकल जाएगा या मेरे टेक्स्ट व्यू में एक लाइन ब्रेक सम्मिलित करेगा। मुझे यह पता लगाने में थोड़ा समय लगा।
  • एक्टिवफिल्ड सक्रिय फ़ील्ड का ट्रैक रखता है यदि कीबोर्ड से फ़ील्ड को अनब्लॉक करने के लिए स्क्रॉलिंग आवश्यक है। यदि आपके पास समान कोड है, तो सुनिश्चित करें कि आपने पहले उत्तरदाता को बदलने से पहले ActiveField असाइन किया है। पहला रिस्पॉन्डर बदलना तत्काल है और कीबोर्डवॉश इवेंट को तुरंत आग लगा देगा।

अच्छा! सरल और कोड सभी एक मॉडल में है। एंथो के रूप में अच्छी तरह से बहुत अच्छा है।
सीमस

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

11

यहां UIControl पर एक श्रेणी का उपयोग करके टैबिंग का कार्यान्वयन है। इस समाधान में माइकल और एंथ0 से तरीकों के सभी फायदे हैं, लेकिन सभी यूआईसीओंट्रोल के लिए काम करता है, न कि केवलUITextField एस । यह इंटरफ़ेस बिल्डर और स्टोरीबोर्ड के साथ भी काम करता है।

स्रोत और नमूना एप्लिकेशन: UIControlsWithTabbing के लिए GitHub रिपॉजिटरी

उपयोग:

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

इंटरफ़ेस बिल्डर में NextControl असाइन करना

हैडर:

//
// UIControl+NextControl.h
// UIControlsWithTabbing
//

#import <UIKit/UIKit.h>

@interface UIControl (NextControl)

@property (nonatomic, weak) IBOutlet UIControl *nextControl;

- (BOOL)transferFirstResponderToNextControl;

@end

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

#import "UIControl+NextControl.h"
#import <objc/runtime.h>

static char defaultHashKey;

@implementation UIControl (NextControl)

- (UIControl *)nextControl
{
    return objc_getAssociatedObject(self, &defaultHashKey);
}

- (void)setNextControl:(UIControl *)nextControl
{
    objc_setAssociatedObject(self, &defaultHashKey, nextControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)transferFirstResponderToNextControl
{
    if (self.nextControl)
    {
        [self.nextControl becomeFirstResponder];

        return YES;
    }

    [self resignFirstResponder];

    return NO;
}

@end

1
कभी-कभी अगला विजेट एक नियंत्रण नहीं होता है अर्थात UITextView और आप वहां भी टैब करना चाह सकते हैं। UITextField से UIResponder के प्रकार को बदलने पर विचार करें।
पेड्रो बोर्ग्स

1
शानदार और शानदार प्रलेखन के साथ काम करता है। मेरी इच्छा है कि मैं इस प्रश्न को कई घंटे पहले नीचे स्क्रॉल करूं। :)
जेवियर कैडिज़

10

मैंने कई कोड आज़माए हैं और आखिरकार, इसने मेरे लिए स्विफ्ट 3.0 नवीनतम [मार्च 2017] में काम किया।

ViewControllerवर्ग विरासत में मिला दिया जाना चाहिए UITextFieldDelegateइस कोड काम कर रहे बनाने के लिए।

class ViewController: UIViewController,UITextFieldDelegate  

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

override func viewDidLoad() {
    userNameTextField.delegate = self
    userNameTextField.tag = 0
    userNameTextField.returnKeyType = UIReturnKeyType.next
    passwordTextField.delegate = self
    passwordTextField.tag = 1
    passwordTextField.returnKeyType = UIReturnKeyType.go
}

उपरोक्त कोड में, returnKeyType = UIReturnKeyType.nextजहां कुंजी पैड रिटर्न कुंजी प्रदर्शित करने के लिए होगी क्योंकि Nextआपके पास अन्य विकल्प भी हैंJoin/Go , आपके आवेदन के आधार पर मान बदलते हैं।

यह textFieldShouldReturnUITextFieldDelegate नियंत्रित की एक विधि है और यहां टैग मूल्य वृद्धि के आधार पर हमारा अगला क्षेत्र चयन है

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
        nextField.becomeFirstResponder()
    } else {
        textField.resignFirstResponder()
        return true;
    }
    return false
 }

यह काम करता है, सिवाय इसके कि इनपुट क्षेत्र है UITextView। किसी भी विचार कैसे संयोजन में यह करने के लिए?
टी

@ T9b आपको वास्तव में क्या चाहिए? आप अपने ऐप में किस प्रकार का नियंत्रण उपयोग कर रहे हैं?
भवानीशाह मो

दो प्रकार के टेक्स्ट इनपुट हैं, पहला है UITextField(टेक्स्ट की सिंगल लाइन दर्ज करें), दूसरा है UITextView(टेक्स्ट की कई लाइनें दर्ज करें)। UITextViewस्पष्ट रूप से इस कोड का जवाब नहीं है लेकिन इसे रूपों में इस्तेमाल किया जा सकता है।
टी

हां केवल UITextField के लिए कोड का यह भाग और क्या आपने UITextView के लिए ईवेंट को संशोधित करने का प्रयास किया है?
BHUVANESH MOHANKUMAR

9

एक पाठ फ़ील्ड से बाहर निकलने के बाद, आप [otherTextField बनेंFirstResponder] को कॉल करते हैं और अगले फ़ील्ड पर फ़ोकस हो जाता है।

यह वास्तव में एक पेचीदा समस्या हो सकती है जिससे निपटने के लिए अक्सर आप स्क्रीन को स्क्रॉल करना चाहेंगे या अन्यथा टेक्स्ट फ़ील्ड की स्थिति को समायोजित कर सकते हैं ताकि संपादन करते समय यह देखना आसान हो। बस टेक्स्ट फ़ील्ड में अलग-अलग तरीकों से आने और बाहर आने के साथ बहुत सारे परीक्षण करना सुनिश्चित करें और हमेशा जल्दी छोड़ना (हमेशा उपयोगकर्ता को अगले क्षेत्र में जाने के बजाय कीबोर्ड को खारिज करने का विकल्प देना, आमतौर पर "में" के साथ नौसेना बार)



7

कीबोर्ड को खारिज करने के लिए एक बहुत ही आसान तरीका जब 'डन' बटन दबाया जाता है:

हेडर में एक नया IBAction बनाएं

- (IBAction)textFieldDoneEditing:(id)sender;

कार्यान्वयन फ़ाइल में (.m फ़ाइल) निम्न विधि जोड़ें:

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

फिर, जब आप IBAction को टेक्स्टफील्ड से लिंक करने के लिए आते हैं - 'डिड एंड ऑन एक्जिट' इवेंट के लिए लिंक।


1
आपका स्वागत है, यह टेक्स्ट फ़ील्ड के माध्यम से नेविगेट नहीं करता है, लेकिन यह कीबोर्ड को बंद करता है और आपको दूसरे फ़ील्ड का चयन करने की अनुमति देता है।
jcrowson

7

Xib में पहला सेट कीबोर्ड रिटर्न कुंजी, अन्यथा आप इसमें कोड लिख सकते हैं viewdidload:

passWord.returnKeyType = UIReturnKeyNext;

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if(textField == eMail) {
        [textField resignFirstResponder];
        [userName becomeFirstResponder];
    }
    if (textField==userName) {
        [textField resignFirstResponder];
        [passWord becomeFirstResponder];
    }
    if (textField==passWord) {
        [textField resignFirstResponder];
        [country becomeFirstResponder];
    }
    if (textField==country) {
        [textField resignFirstResponder];
    }
    return YES;
}

7

मुझे आश्चर्य है कि यहां कितने उत्तर एक सरल अवधारणा को समझने में विफल रहते हैं: अपने ऐप में नियंत्रण के माध्यम से नेविगेट करना कुछ ऐसा नहीं है जो कि विचारों को स्वयं करना चाहिए। यह नियंत्रक है का काम है जो यह तय करे कि अगला पहला उत्तरदाता कौन सा नियंत्रण करे।

इसके अलावा अधिकांश उत्तर केवल आगे नेविगेट करने के लिए लागू होते हैं, लेकिन उपयोगकर्ता भी पीछे की ओर जाना चाह सकते हैं।

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

#pragma mark - Key Commands

- (NSArray *)keyCommands
{
    static NSArray *commands;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(tabForward:)];
        UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(tabBackward:)];

        commands = @[forward, backward];
    });

    return commands;
}

- (void)tabForward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.firstObject becomeFirstResponder];
}

- (void)tabBackward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls.reverseObjectEnumerator) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.lastObject becomeFirstResponder];
}

पहले से दिखाई देने वाले ऑफ़स्क्रीन उत्तरदाताओं को स्क्रॉल करने का अतिरिक्त तर्क लागू हो सकता है।

इस दृष्टिकोण का एक और लाभ यह है कि आपको उन सभी प्रकार के नियंत्रणों को उप-वर्गित करने की आवश्यकता नहीं है जिन्हें आप प्रदर्शित करना चाहते हैं (जैसे UITextFields), लेकिन इसके बजाय नियंत्रक स्तर पर तर्क का प्रबंधन कर सकते हैं, जहाँ, हम ईमानदार रहें, ऐसा करने के लिए सही जगह है ।


मुझे आपका जवाब सबसे अधिक प्रासंगिक लगता है, लेकिन मैंने कुछ मजेदार बात नोटिस की है जो शायद आप स्पष्ट कर सकते हैं। UIVextCields द्वारा UITextFields का उपयोग नहीं किए जाने पर, टैब कुंजी दबाने पर अगला UITextField डिफ़ॉल्ट रूप से पहला उत्तरदाता बना देगा। हालाँकि, जब प्रत्येक को VC द्वारा प्रबंधित किया जाता है, यह सच नहीं है। मेरे वीसी कुछ नहीं कर रहे हैं, लेकिन टैबिंग कार्यक्षमता में बनाया गया है। मैंने देखा है कि वीसी के की-बोर्ड समाप्त होते हैं, जो दृश्य के उत्तरदाता श्रृंखला में जोड़े जाते हैं। यह मुझे विश्वास दिलाता है कि यदि आप वीसी का उपयोग कर रहे हैं, तो की-बोर्ड लागू करना अनिवार्य है।
जोए कार्सन

4

यदि आपने पिछली / अगली बटन कार्यक्षमता लागू करना चाहते हैं, तो मैंने PeyloW के उत्तर में जोड़ा है:

- (IBAction)moveThroughTextFields:(UIBarButtonItem *)sender 
{
    NSInteger nextTag;
    UITextView *currentTextField = [self.view findFirstResponderAndReturn];

    if (currentTextField != nil) {
        // I assigned tags to the buttons.  0 represent prev & 1 represents next
        if (sender.tag == 0) {
            nextTag = currentTextField.tag - 1;

        } else if (sender.tag == 1) {
            nextTag = currentTextField.tag + 1;
        }
    }
    // Try to find next responder
    UIResponder* nextResponder = [self.view viewWithTag:nextTag];
    if (nextResponder) {
        // Found next responder, so set it.
        // I added the resign here in case there's different keyboards in place.
        [currentTextField resignFirstResponder];
        [nextResponder becomeFirstResponder];
    } else {
        // Not found, so remove keyboard.
        [currentTextField resignFirstResponder];

    }
}

जहाँ आप इस तरह से UIView उपवर्ग:

@implementation UIView (FindAndReturnFirstResponder)
- (UITextView *)findFirstResponderAndReturn
{
    for (UITextView *subView in self.subviews) {
        if (subView.isFirstResponder){
            return subView;
        }
    }
    return nil;
}
@end

4

हाय हर किसी के लिए कृपया देखें यह एक

- (void)nextPrevious:(id)sender
{

  UIView *responder = [self.view findFirstResponder];   

  if (nil == responder || ![responder isKindOfClass:[GroupTextField class]]) {
    return;
  }

  switch([(UISegmentedControl *)sender selectedSegmentIndex]) {
    case 0:
      // previous
      if (nil != ((GroupTextField *)responder).previousControl) {
        [((GroupTextField *)responder).previousControl becomeFirstResponder];
        DebugLog(@"currentControl: %i previousControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).previousControl.tag);
      }
      break;
    case 1:
      // next
      if (nil != ((GroupTextField *)responder).nextControl) {
        [((GroupTextField *)responder).nextControl becomeFirstResponder];
        DebugLog(@"currentControl: %i nextControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).nextControl.tag);
      }     
      break;    
  }
}

UIView * रिस्पॉन्डर के बजाय UIRespoder * रिस्पॉन्डर का उपयोग करना अधिक सटीक होगा
Pedro Borges

4

मैंने एक अद्वितीय टैग मान UITextFieldमें प्रत्येक सेल (या ) को असाइन करने के आधार पर अधिक परिष्कृत दृष्टिकोण का उपयोग करके इस समस्या को हल करने की कोशिश की, UITableViewजिसे पुनर्प्राप्त किया जा सकता है: सक्रिय-अगला-यूटेक्स्टफील्ड-इन-यूएटिव्यू-आईओएस

आशा है कि ये आपकी मदद करेगा!


4

मैंने इस सामान GNTextFieldsCollectionManager से निपटने के दौरान नया पॉड बनाया है । यह स्वचालित रूप से अगली / अंतिम टेक्स्टफ़िल्ड समस्या को संभालता है और इसका उपयोग करना बहुत आसान है:

[[GNTextFieldsCollectionManager alloc] initWithView:self.view];

पदानुक्रम (या टैग द्वारा) को देखने के द्वारा छांटे गए सभी टेक्स्ट फ़ील्ड को पकड़ लेता है, या आप टेक्स्ट फ़ील्ड के अपने स्वयं के सरणी को निर्दिष्ट कर सकते हैं।


4

स्विफ्ट 3.1 में समाधान, अपने टेक्स्टफील्ड्स को कनेक्ट करने के बाद IBOutlets ने अपने टेक्स्टफिल्ड डेलीगेट को व्यूडैलाड में सेट किया है, और फिर टेक्स्टफिल्डशोल्डरटर्न में अपनी कार्रवाई नेविगेट करें।

class YourViewController: UIViewController,UITextFieldDelegate {

        @IBOutlet weak var passwordTextField: UITextField!
        @IBOutlet weak var phoneTextField: UITextField!

        override func viewDidLoad() {
            super.viewDidLoad()
            self.passwordTextField.delegate = self
            self.phoneTextField.delegate = self
            // Set your return type
            self.phoneTextField.returnKeyType = .next
            self.passwordTextField.returnKeyType = .done
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool{
            if textField == self.phoneTextField {
                self.passwordTextField.becomeFirstResponder()
            }else if textField == self.passwordTextField{
                // Call login api
                self.login()
            }
            return true
        }

    }

4

अगर कोई ऐसा चाहता है। मुझे लगता है कि यह प्रश्न में पूछी गई आवश्यकताओं के सबसे करीब है

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

यहां बताया गया है कि मैंने इसे कैसे लागू किया है

प्रत्येक पाठ फ़ील्ड के लिए एक्सेसरी दृश्य जोड़ें, जिसके लिए आप सेटअप का उपयोग करना चाहते हैं

func setAccessoryViewFor(textField : UITextField)    {
    let toolBar = UIToolbar()
    toolBar.barStyle = .default
    toolBar.isTranslucent = true
    toolBar.sizeToFit()

    // Adds the buttons

    // Add previousButton
    let prevButton = UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(previousPressed(sender:)))
    prevButton.tag = textField.tag
    if getPreviousResponderFor(tag: textField.tag) == nil {
        prevButton.isEnabled = false
    }

    // Add nextButton
    let nextButton = UIBarButtonItem(title: ">", style: .plain, target: self, action: #selector(nextPressed(sender:)))
    nextButton.tag = textField.tag
    if getNextResponderFor(tag: textField.tag) == nil {
        nextButton.title = "Done"
    }

    let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    toolBar.setItems([prevButton,spaceButton,nextButton], animated: false)
    toolBar.isUserInteractionEnabled = true
    textField.inputAccessoryView = toolBar
}

नल को संभालने के लिए निम्न कार्यों का उपयोग करें

func nextPressed(sender : UIBarButtonItem) {
    if let nextResponder = getNextResponderFor(tag: sender.tag) {
        nextResponder.becomeFirstResponder()
    } else {
        self.view.endEditing(true)
    }

}

func previousPressed(sender : UIBarButtonItem) {
    if let previousResponder = getPreviousResponderFor(tag : sender.tag)  {
        previousResponder.becomeFirstResponder()
    }
}

func getNextResponderFor(tag : Int) -> UITextField? {
    return self.view.viewWithTag(tag + 1) as? UITextField
}

func getPreviousResponderFor(tag : Int) -> UITextField? {
    return self.view.viewWithTag(tag - 1) as? UITextField
}

आपको टेक्स्टफिल्ड टैग को उस क्रम में देना होगा, जिसमें आप अगला / प्रचलित बटन चाहते हैं।


3

मैं इसके बजाय पसंद करता हूं:

@interface MyViewController : UIViewController
@property (nonatomic, retain) IBOutletCollection(UIView) NSArray *inputFields;
@end

NIB फ़ाइल में मैं इस inputFields सरणी में वांछित क्रम में textFields हुक। उसके बाद मैं UITextField के सूचकांक के लिए एक साधारण परीक्षण करता हूं, जो रिपोर्ट करता है कि उपयोगकर्ता ने प्रतिफल दिया है:

// for UITextField
-(BOOL)textFieldShouldReturn:(UITextField*)textField {
    NSUInteger index = [_inputFields indexOfObject:textField];
    index++;
    if (index < _inputFields.count) {
        UIView *v = [_inputFields objectAtIndex:index];
        [v becomeFirstResponder];
    }
    return NO;
}

// for UITextView
-(BOOL)textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {
    if ([@"\n" isEqualToString:text]) {
        NSUInteger index = [_inputFields indexOfObject:textView];
        index++;
        if (index < _inputFields.count) {
            UIView *v = [_inputFields objectAtIndex:index];
            [v becomeFirstResponder];
        } else {
            [self.view endEditing:YES];
        }
        return NO;
    }
    return YES;
}

3
अगर (सेल == नील)
{
    सेल = [[UITableViewCell आवंटन] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: cellIdentifier];
    txt_Input = [[UITextField आवंटित] initWithFrame: CGRectMake (0, 10, 150, 30)];
    txt_Input.tag = indexPath.row + 1;
    [self.array_Textfields addObject: txt_Input]; // ViewDidLoad में परिवर्तनशील सारणी को आरम्भ करें
}

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

    int tag = (int) textField.tag;
    UITextField * txt = [self.array_Textfields objectAtIndex: tag];
    [txt बनोFirstResponder];
    हाँ लौटाना;
}

3

मेरी कहानी बोर्ड में लगभग 10+ UITextField थी और जिस तरह से मैंने अगली कार्यक्षमता को सक्षम किया था वह UITextField की एक सरणी बनाकर और अगले UITextField को FirstResponder बना दिया था। यहाँ कार्यान्वयन फ़ाइल है:

#import "RegistrationTableViewController.h"

@interface RegistrationTableViewController ()
@property (weak, nonatomic) IBOutlet UITextField *fullNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet UITextField *address2TextField;
@property (weak, nonatomic) IBOutlet UITextField *cityTextField;
@property (weak, nonatomic) IBOutlet UITextField *zipCodeTextField;
@property (weak, nonatomic) IBOutlet UITextField *urlTextField;
@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@property (weak, nonatomic) IBOutlet UITextField *confirmPWTextField;

@end
NSArray *uiTextFieldArray;
@implementation RegistrationTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"view did load");
    uiTextFieldArray = @[self.fullNameTextField,self.addressTextField,self.address2TextField,self.cityTextField,self.zipCodeTextField,self.urlTextField,self.usernameTextField,self.emailTextField,self.passwordTextField,self.confirmPWTextField];
    for(UITextField *myField in uiTextFieldArray){
        myField.delegate = self;
    }


}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    long index = [uiTextFieldArray indexOfObject:textField];
    NSLog(@"%ld",index);
    if(index < (uiTextFieldArray.count - 1)){
        [uiTextFieldArray[++index] becomeFirstResponder];
    }else{
        [uiTextFieldArray[index] resignFirstResponder];
    }
    return YES;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

3

इसने मेरे लिए Xamarin.iOS / Monotouch में काम किया। कीबोर्ड बटन को नेक्स्ट में बदलें, कंट्रोल को अगले UITextField में पास करें और आखिरी UITextField के बाद कीबोर्ड को छिपाएं।

private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{
  foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField)))
  {
    (item as UITextField).ReturnKeyType = UIReturnKeyType.Next;
    (item as UITextField).ShouldReturn += (textField) =>
    {
        nint nextTag = textField.Tag + 1;
        var nextResponder = textField.Superview.ViewWithTag(nextTag);
        if (null != nextResponder)
            nextResponder.BecomeFirstResponder();
        else
            textField.Superview.EndEditing(true); 
            //You could also use textField.ResignFirstResponder(); 

        return false; // We do not want UITextField to insert line-breaks.
    };
  }
}

ViewDidLoad के अंदर आपके पास होगा:

यदि आपके TextFields ने अभी टैग नहीं लगाया है:

txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...

और सिर्फ कॉल

SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

3

यह स्विफ्ट में एक सरल उपाय है, जिसमें कोई टैग का उपयोग नहीं किया गया है, कोई स्टोरीबोर्ड ट्रिक्स नहीं है ...

बस इस एक्सटेंशन का उपयोग करें:

extension UITextField{

    func nextTextFieldField() -> UITextField?{
        //field to return
        var returnField : UITextField?
        if self.superview != nil{
            //for each view in superview
            for (_, view) in self.superview!.subviews.enumerate(){
                //if subview is a text's field
                if view.isKindOfClass(UITextField){
                    //cast curent view as text field
                    let currentTextField = view as! UITextField
                    //if text field is after the current one
                    if currentTextField.frame.origin.y > self.frame.origin.y{
                        //if there is no text field to return already
                        if returnField == nil {
                            //set as default return
                            returnField = currentTextField
                        }
                            //else if this this less far than the other
                        else if currentTextField.frame.origin.y < returnField!.frame.origin.y{
                            //this is the field to return
                            returnField = currentTextField
                        }
                    }
                }
            }
        }
        //end of the mdethod
        return returnField
    }

}

और इसे इस तरह से (उदाहरण के लिए) अपने टेक्स्टफील्ड प्रतिनिधि के साथ कॉल करें:

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

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

3

एक सुरक्षित और अधिक प्रत्यक्ष तरीका,

  • पाठ फ़ील्ड प्रतिनिधि आपके दृश्य नियंत्रक पर सेट हैं
  • सभी पाठ फ़ील्ड एक ही दृश्य के साक्षात्कार हैं
  • पाठ फ़ील्ड में आपके द्वारा प्रगति के लिए दिए गए टैग हैं (जैसे, textField2.tag = 2, textField3.tag = 3, आदि)
  • अगले टेक्स्ट फ़ील्ड पर जाना तब होगा जब आप कीबोर्ड पर रिटर्न बटन टैप करेंगे (आप इसे अगले , किए गए , आदि के लिए बदल सकते हैं )
  • आप अंतिम टेक्स्ट फ़ील्ड के बाद कीबोर्ड को खारिज करना चाहते हैं

स्विफ्ट 4.1:

extension ViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let nextTag = textField.tag + 1
        guard let nextTextField = textField.superview?.viewWithTag(nextTag) else {
            textField.resignFirstResponder()
            return false
        }

    nextTextField.becomeFirstResponder()

    return false

    }
}

2

textFieldShouldReturn में आपको यह जांचना चाहिए कि जिस टेक्स्टफील्ड पर आप वर्तमान में हैं, वह अंतिम एक नहीं है जब वे अगले क्लिक करते हैं और यदि इसका n ot कीबोर्ड को खारिज नहीं करता है ..


अरे, यह ठीक है, लेकिन मैं "नेक्स्ट" बटन के साथ अगले टेक्स्टफील्ड पर कैसे जा सकता हूं?
phx

2

यह एक पुरानी पोस्ट है, लेकिन एक उच्च पेज रैंक है इसलिए मैं अपने समाधान के साथ झंकार करूंगा।

मेरे पास एक समान मुद्दा था और UIToolbarएक गतिशील तालिका दृश्य में अगले / पिछले / किए गए कार्यक्षमता को प्रबंधित करने के लिए एक उपवर्ग बना रहा था। अनुभागों के साथ: https://github.com/jday001/DataEntryToolbar

आप टूलबार को अपने टेक्स्ट फ़ील्ड के inputAccessoryView के रूप में सेट करते हैं और उन्हें इसके शब्दकोश में जोड़ते हैं। यह आपको गतिशील सामग्री के साथ, आगे और पीछे उनके माध्यम से चक्र करने की अनुमति देता है। यदि आप टेक्स्टफ़ीड नेविगेशन होता है, तो अपनी स्वयं की कार्यक्षमता को ट्रिगर करना चाहते हैं, तो प्रतिनिधि विधियाँ हैं, लेकिन आपको किसी भी टैग या पहली उत्तरदाता स्थिति को प्रबंधित करने की आवश्यकता नहीं है।

कार्यान्वयन विवरण के साथ सहायता के लिए GitHub लिंक पर कोड स्निपेट और एक उदाहरण ऐप हैं। खेतों के अंदर के मूल्यों पर नज़र रखने के लिए आपको अपने स्वयं के डेटा मॉडल की आवश्यकता होगी।


2

बिना टैग्स के और टैग्स के बिना नेक्स्टफिल्ड / नेक्स्ट टेक्स्टफिल्ड के लिए कोई प्रॉपर्टी जोड़ने के बिना, आप TAB का अनुकरण करने के लिए यह कोशिश कर सकते हैं, जहां "testInput" आपका वर्तमान सक्रिय क्षेत्र है:

if ([textInput isFirstResponder])
    [textInput.superview.subviews enumerateObjectsAtIndexes:
     [NSIndexSet indexSetWithIndexesInRange:
      NSMakeRange([textInput.superview.subviews indexOfObject:textInput]+1,
                  [textInput.superview.subviews count]-[textInput.superview.subviews indexOfObject:textInput]-1)]
                                                    options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
                                                        *stop = !obj.hidden && [obj becomeFirstResponder];
                                                    }];
if ([textInput isFirstResponder])
    [textInput.superview.subviews enumerateObjectsAtIndexes:
     [NSIndexSet indexSetWithIndexesInRange:
      NSMakeRange(0,
                  [textInput.superview.subviews indexOfObject:textInput])]
                                                    options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
                                                        *stop = !obj.hidden && [obj becomeFirstResponder];
                                                    }];

2

मैं माइकल जी। एममन्स के जवाब के बारे में एक साल के लिए उपयोग कर रहा हूं, अब बढ़िया काम करता है। मैंने हाल ही में नोटिस किया कि resignFirstResponder को कॉल करना और फिर तुरंतFirstResponder हो जाना कीबोर्ड को "गड़बड़", गायब होने और फिर तुरंत दिखाई देने का कारण बन सकता है। अगर अगला उपलब्ध है तो मैंने इस्तीफा देने के लिए अपना संस्करण थोड़ा बदल दिया।

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

    अगर ([textField isKindOfClass: [NRTextField वर्ग]]]
    {
        NRTextField * nText = (NRTextField *) textField;
        अगर ([nText nextField]! = nil) {
            dispatch_async (dispatch_get_main_queue (),
                           ^ {[[नेक्स्ट नेक्स्टफिल्ड] बन फ़र्स्ट रेस्पेन्डर]; });

        }
        अन्य{
            [textField resignFirstResponder];
        }
    }
    अन्य{
        [textField resignFirstResponder];
    }

    सच लौटना;

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