ios - UITextField पाठ परिवर्तन घटना




objective-c swift (12)

मैं टेक्स्ट फ़ील्ड में किसी भी टेक्स्ट परिवर्तन का पता कैसे लगा सकता हूं? प्रतिनिधि विधि को shouldChangeCharactersInRange कुछ के लिए काम करता है, लेकिन यह मेरी ज़रूरत को पूरा नहीं करता है। चूंकि यह यस लौटाता है, तब तक टेक्स्टफिल्ल्ड ग्रंथ अन्य पर्यवेक्षक विधियों के लिए उपलब्ध नहीं हैं।

उदाहरण के लिए मेरे कोड की calculateAndUpdateTextFields औरUpdateTextFields को अद्यतन पाठ नहीं मिला, उपयोगकर्ता ने टाइप किया है।

textChanged जावा इवेंट हैंडलर जैसे कुछ पाने का उनका कोई तरीका है।

- (BOOL)textField:(UITextField *)textField 
            shouldChangeCharactersInRange:(NSRange)range 
            replacementString:(NSString *)string 
{
    if (textField.tag == kTextFieldTagSubtotal 
        || textField.tag == kTextFieldTagSubtotalDecimal
        || textField.tag == kTextFieldTagShipping
        || textField.tag == kTextFieldTagShippingDecimal) 
    {
        [self calculateAndUpdateTextFields];

    }

    return YES;
}

https://code.i-harness.com


XenElement का जवाब स्पॉट पर है।

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


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

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:)
                                                 name:@"UITextFieldTextDidChangeNotification"
                                               object:youTarget];

फिर

- (void)textFiledEditChanged:(NSNotification *)obj {
UITextField *textField = (UITextField *)obj.object;
NSString *toBestring = textField.text;
NSArray *currentar = [UITextInputMode activeInputModes];
UITextInputMode *currentMode = [currentar firstObject];
if ([currentMode.primaryLanguage isEqualToString:@"zh-Hans"]) {
    UITextRange *selectedRange = [textField markedTextRange];
    UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
    if (!position) {
        if (toBestring.length > kMaxLength)
            textField.text =  toBestring;
} 

}

अंत में, आप भाग लेंगे, किया जाएगा।


जैसा कि यहां बताया गया है: UITextField टेक्स्ट चेंज इवेंट , ऐसा लगता है कि आईओएस 6 (आईओएस 6.0 और 6.1 चेक) के रूप में UITextField को देखकर UITextField ऑब्जेक्ट्स में बदलावों को पूरी तरह से UITextField संभव नहीं है।

ऐसा लगता है कि अंतर्निहित आईओएस कीबोर्ड द्वारा सीधे किए गए केवल इन परिवर्तनों को ट्रैक किया जाता है। इसका अर्थ यह है कि यदि आप अपनी UITextField ऑब्जेक्ट को इस तरह कुछ आमंत्रित करके myUITextField.text = @"any_text" : myUITextField.text = @"any_text" , आपको किसी भी बदलाव के बारे में अधिसूचित नहीं किया जाएगा।

मुझे नहीं पता कि यह एक बग है या इसका इरादा है। एक बग की तरह लगता है क्योंकि मुझे दस्तावेज़ीकरण में कोई उचित स्पष्टीकरण नहीं मिला है। यह यहां भी कहा गया है: UITextField टेक्स्ट चेंज इवेंट

इसके लिए मेरा "समाधान" वास्तव में मेरे UITextField गए प्रत्येक बदलाव के लिए एक अधिसूचना पोस्ट करना है (यदि वह परिवर्तन अंतर्निहित आईओएस कीबोर्ड का उपयोग किए बिना किया जाता है)। कुछ इस तरह:

myUITextField.text = @"I'm_updating_my_UITextField_directly_in_code";

NSNotification *myTextFieldUpdateNotification  = 
  [NSNotification notificationWithName:UITextFieldTextDidChangeNotification
                  object:myUITextField];

[NSNotificationCenter.defaultCenter 
  postNotification:myTextFieldUpdateNotification];

इस तरह आप 100% आत्मविश्वास रखते हैं कि जब आप अपने कोड में या अंतर्निहित आईओएस कीबोर्ड के माध्यम से इसे "मैन्युअल" अपडेट करते हैं, तो आप अपनी UITextField ऑब्जेक्ट की .text प्रॉपर्टी को बदलते समय भी वही अधिसूचना प्राप्त करेंगे।

यह मानना ​​महत्वपूर्ण है कि, चूंकि यह एक दस्तावेज व्यवहार नहीं है, इसलिए इस दृष्टिकोण से आपके UITextField ऑब्जेक्ट में एक ही बदलाव के लिए 2 अधिसूचनाएं प्राप्त हो सकती हैं। आपकी ज़रूरतों के आधार पर (आप वास्तव में क्या करते हैं जब आपका UITextField.text बदलता है) यह आपके लिए असुविधा हो सकती है।

यदि आपको वास्तव में यह पता होना चाहिए कि अधिसूचना आपकी थी या "आईओएस-निर्मित" है, तो आपको एक कस्टम अधिसूचना पोस्ट करना होगा (यह है, UITextFieldTextDidChangeNotification अलावा कस्टम नाम के साथ)।

संपादित करें:

मुझे अभी एक अलग दृष्टिकोण मिला है जो मुझे लगता है कि बेहतर हो सकता है:

इसमें उद्देश्य-सी ( http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA की कुंजी-मूल्य निरीक्षण (केवीओ) सुविधा शामिल है http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA )।

असल में, आप खुद को एक संपत्ति के पर्यवेक्षक के रूप में पंजीकृत करते हैं और यदि यह संपत्ति बदलती है तो आपको इसके बारे में अधिसूचित किया जाता है। "सिद्धांत" NSNotificationCenter काम करता है, यह मुख्य लाभ है कि यह दृष्टिकोण आईओएस 6 के रूप में स्वचालित रूप से भी काम करता है (बिना किसी विशेष NSNotificationCenter मैन्युअल रूप से अधिसूचनाएं पोस्ट करने के लिए)।

हमारे UITextField -scenario के लिए यह ठीक काम करता है यदि आप इस कोड को जोड़ते हैं, उदाहरण के लिए, आपका UIViewController जिसमें टेक्स्ट फ़ील्ड है:

static void *myContext = &myContext;

- (void)viewDidLoad {
  [super viewDidLoad];

  //Observing changes to myUITextField.text:
  [myUITextField addObserver:self forKeyPath:@"text"
    options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld 
    context:myContext];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context {

  if(context == myContext) {
    //Here you get notified every time myUITextField's "text" property is updated
    NSLog(@"New value: %@ - Old value: %@",
      [change objectForKey:NSKeyValueChangeNewKey],
      [change objectForKey:NSKeyValueChangeOldKey]);
  }
  else 
    [super observeValueForKeyPath:keyPath ofObject:object 
      change:change context:context];

}

"संदर्भ" प्रबंधन के संबंध में इस उत्तर का श्रेय: https://.com/a/12097161/2078512

नोट: ऐसा लगता है कि जब आप अंतर्निहित आईओएस कीबोर्ड के साथ UITextField को संपादित करने की प्रक्रिया में हैं, तो टेक्स्ट फ़ील्ड की "टेक्स्ट" प्रॉपर्टी टाइप / हटाए गए प्रत्येक नए अक्षर के साथ अपडेट नहीं की जाती है। इसके बजाय, पाठ फ़ील्ड ऑब्जेक्ट को टेक्स्ट फ़ील्ड की पहली प्रतिक्रियाकर्ता स्थिति से इस्तीफा देने के बाद "संपूर्ण रूप से" अपडेट हो जाता है।


बंद होने के साथ:

   class TextFieldWithClosure: UITextField {
    var targetAction: (() -> Void)? {
        didSet {
            self.addTarget(self, action: #selector(self.targetSelector), for: .editingChanged)
        }
    }

    func targetSelector() {
        self.targetAction?()
    }
    }

और उपयोग कर रहे हैं

textField.targetAction? = {
 // will fire on text changed
 }

यहां के लिए तेज़ संस्करण में।

textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)

func textFieldDidChange(textField: UITextField) {

}

धन्यवाद


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

class SomeClass: UIViewController, UITextFieldDelegate { 

   @IBOutlet weak var aTextField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        aTextField.delegate = self
        aTextField.addTarget(self, action: #selector(SignUpVC.textFieldDidChange), for: UIControlEvents.editingChanged)        
    }

   func textFieldDidChange(_ textField: UITextField) {

       //TEXT FIELD CHANGED..SECRET STUFF

   }

}

प्रतिनिधि को सेट करना न भूलें।


स्विफ्ट 3.1:

चयनकर्ता: ClassName.MethodName

  cell.lblItem.addTarget(self, action: #selector(NewListScreen.fieldChanged(textfieldChange:)), for: .editingChanged)

  func fieldChanged(textfieldChange: UITextField){

    }

हम Storyboard से आसानी से कॉन्फ़िगर कर सकते हैं, CTRL @IBAction खींचें और ईवेंट को निम्नानुसार बदलें:


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

yourTextField.addTarget(self, action: #selector(YourControllerName.textChanges(_:)), for: UIControlEvents.editingChanged)

और यहां परिवर्तन प्राप्त करें

func textChanges(_ textField: UITextField) {
    let text = textField.text! // your desired text here
    // Now do whatever you want.
}

आशा करता हूँ की ये काम करेगा।


स्विफ्ट 3

@IBAction func textfildChange(sender: UITextField) {
        if let number = sender.text {
            if number.isEmpty {

            } else {
               print(number)
            }
        }
    }

स्विफ्ट संस्करण का परीक्षण किया गया:

//Somewhere in your UIViewController, like viewDidLoad(){ ... }
self.textField.addTarget(
        self, 
        action: #selector(SearchViewController.textFieldDidChange(_:)),
        forControlEvents: UIControlEvents.EditingChanged
)

पैरामीटर्स ने समझाया:

self.textField //-> A UITextField defined somewhere in your UIViewController
self //-> UIViewController
.textFieldDidChange(_:) //-> Can be named anyway you like, as long as it is defined in your UIViewController

फिर अपने UIViewController में ऊपर बनाई गई विधि जोड़ें:

//Gets called everytime the text changes in the textfield.
func textFieldDidChange(textField: UITextField){

    print("Text changed: " + textField.text!)

}

स्विफ्ट:

yourTextfield.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)

फिर, कॉलबैक फ़ंक्शन को लागू करें:

@objc func textFieldDidChange(textField: UITextField){

print("Text changed")

}






uitextfielddelegate