खाली UITextField में बैकस्पेस का पता लगाएं


126

क्या यह पता लगाने का कोई तरीका है कि iPhone कीबोर्ड में Backspace/ Deleteकी को दबाया गया UITextFieldहै या खाली है? मैं जानना चाहता हूं कि खाली होने पर Backspaceही दबाया UITextFieldजाता है।


एक टिप्पणी में @ एलेक्स रेनॉल्ड्स के सुझाव के आधार पर, मैंने अपना पाठ फ़ील्ड बनाते समय निम्नलिखित कोड जोड़ा है:

[[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(handleTextFieldChanged:)
              name:UITextFieldTextDidChangeNotification
            object:searchTextField];

यह सूचना प्राप्त होती है ( handleTextFieldChangedफ़ंक्शन कहा जाता है), लेकिन तब भी नहीं जब मैं Backspaceएक खाली फ़ील्ड में कुंजी दबाता हूं । कोई विचार?


इस प्रश्न के बारे में कुछ भ्रम प्रतीत होता है। जब Backspaceकुंजी दबाया जाता है तो मैं एक अधिसूचना प्राप्त करना चाहता हूं । बस। लेकिन समाधान भी काम करना चाहिए जब UITextFieldपहले से ही खाली है।


मुझे लगता है कि आपका मतलब "केवल तभी हो सकता है यदि UITextField खाली है" बजाय "केवल कीबोर्ड खाली है तो" ...?
स्टीव हैरिसन

@ सर्वेश हैरिसन: धन्यवाद। अपडेट किया गया है कि
marcc

मैं कुछ ऐसा ही करने की कोशिश कर रहा हूं, तब आपको क्या समाधान मिला? मैं जो कर रहा हूं वह स्क्रॉल दृश्य में एक टेक्स्ट फ़ील्ड है, जब मैं कुछ टेक्स्ट टाइप करता हूं, तो सुझाव दिखाए जाते हैं और जब मैं एक क्लिक करता हूं, तो टेक्स्ट फ़ील्ड के बाईं ओर एक लेबल ऑब्जेक्ट रखा जाता है। अग्रिम धन्यवाद: डी
आटा

2011/11 के लिए खाली UITextField के लिए समाधान रनटाइम ट्रिकरी का उपयोग कर:2011-2011 के bjhomer.blogspot.com/2011/11/…
Jano

4
बहुत तुच्छ कुछ के लिए लंबे समय तक। यह मुश्किल नहीं होना चाहिए।
एडम वेट

जवाबों:


36

यह एक लंबा शॉट हो सकता है लेकिन यह काम कर सकता है। पाठ क्षेत्र के पाठ को शून्य चौड़ाई वाले स्थान वर्ण पर सेट करने का प्रयास करें \u200B। जब बैकस्पेस एक टेक्स्ट फ़ील्ड पर दबाया जाता है जो खाली दिखाई देता है, तो यह वास्तव में आपके स्थान को हटा देगा। तब आप केवल अंतरिक्ष को पुन: स्थापित कर सकते हैं।

यदि उपयोगकर्ता अंतरिक्ष के बाईं ओर कैरेट को स्थानांतरित करने का प्रबंधन करता है तो काम नहीं कर सकता।


3
@ और, यह वह तरीका है जिसे मैंने लेने का फैसला किया है। इसने थोड़ा सा कोड लिया, लेकिन यह निश्चित रूप से प्रभावी है। मदद के लिए धन्यवाद के बजाय मुझे बताने की कोशिश कर रहा हूँ कि मैं कुछ गलत कर रहा हूँ।
marcc

2
यह तकनीक iPhone> 3.1.3 पर काम कर सकती है, लेकिन यह हैकरी है और भविष्य के संस्करणों पर टूट सकती है, आदि मुझे लगता है कि मुझे iPhone / iOS पर एक डिलीट कीबोर्ड की प्रेस का पता लगाने के तरीके के लिए एक क्लीनर, अधिक स्थिर समाधान मिला ।
ma11hew28

6
अगर उपयोगकर्ता कर्सर को अंतरिक्ष के बाईं ओर ले जाने का प्रबंधन करता है, तो मैं पुष्टि कर सकता हूं कि डिलीट का पता नहीं चला है। आप पता लगा सकते हैं कि ठीक करने का तरीका है, तो आप भी उपवर्ग चाहिए UITextFieldऔर लागू canPerformAction:withSender:करने के लिए return NOके लिए select:और selectAll:कार्रवाई जब पाठ स्ट्रिंग के बराबर है @"\u200B"
ma11hew28

2
समस्या यह है कि यह सुरक्षित परीक्षण क्षेत्रों के लिए काम नहीं करता है। किसी भी विचारों को कैसे संभालना है?
काइल क्लेग

7
क्षमा करें, लेकिन यह विचार बुरा है। यह अविश्वसनीय हैकी है और 30 या इसके बाद के संस्करण के साथ स्वीकृत उत्तर नहीं होना चाहिए। मैं UITextField की जगह सबक्लास करूंगा, जैसे कि कुछ अन्य टिप्पणीकारों ने उल्लेख किया है।
ब्रायन सचेटा

155

स्विफ्ट 4:


उपवर्ग UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate: AnyObject {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        super.deleteBackward()
        myDelegate?.textFieldDidDelete()
    }

}

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

// ViewController.swift

import UIKit

class ViewController: UIViewController, MyTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // initialize textField
        let input = MyTextField(frame: CGRect(x: 50, y: 50, width: 150, height: 40))

        // set viewController as "myDelegate"
        input.myDelegate = self

        // add textField to view
        view.addSubview(input)

        // focus the text field
        input.becomeFirstResponder()
    }

    func textFieldDidDelete() {
        print("delete")
    }

}

उद्देश्य सी:


उपवर्ग UITextField:

//Header
//MyTextField.h

//create delegate protocol
@protocol MyTextFieldDelegate <NSObject>
@optional
- (void)textFieldDidDelete;
@end

@interface MyTextField : UITextField<UIKeyInput>

//create "myDelegate"
@property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate;
@end

//Implementation
#import "MyTextField.h"

@implementation MyTextField

- (void)deleteBackward {
    [super deleteBackward];

    if ([_myDelegate respondsToSelector:@selector(textFieldDidDelete)]){
        [_myDelegate textFieldDidDelete];
    }
}

@end

अब बस जोड़ने MyTextFieldDelegate अपने को UIViewControllerऔर अपने सेट UITextFields myDelegate लिए self:

//View Controller Header
#import "MyTextField.h"

//add "MyTextFieldDelegate" to you view controller
@interface ViewController : UIViewController <MyTextFieldDelegate>
@end

//View Controller Implementation
- (void)viewDidLoad {
    //initialize your text field
    MyTextField *input = 
     [[MyTextField alloc] initWithFrame:CGRectMake(0, 0, 70, 30)];

    //set your view controller as "myDelegate"
    input.myDelegate = self;

    //add your text field to the view
    [self.view addSubview:input];
}

//MyTextField Delegate
- (void)textFieldDidDelete {
    NSLog(@"delete");
}

9
यह सबसे अच्छा उपाय है। स्वीकृत उत्तर हैक है। ऑब्जेक्टिव सी सब क्लासिंग पर आधारित है और यह समाधान समस्या को हल करने के लिए इसका सही उपयोग करता है।
TJ

में मेरे मौजूदा प्रतिनिधि तरीकों का क्या होगा ViewController वर्ग अगर मैं के उपवर्ग के लिए मेरे पाठ फ़ील्ड के प्रतिनिधि सेट UITextFieldके बजायUIViewController
रोहन-पटेल

4
यह जाहिरा तौर पर अभी ios8 में काम नहीं करता है, जो कि Apple बग जैसा लगता है: devforums.apple.com/message/1045312#1045312
chug2k

1
मैंने अपने उत्तर में ios8 बग के लिए समाधान समाधान का उपयोग किया और यह काम किया। यह उन लोगों के लिए उपयोगी हो सकता है जो समाधान की तलाश कर रहे हैं।
४ay बजे

1
deleteBackward()अगर आप return falseको बुलाया नहीं जाएगाtextField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
igrrik

41

अपडेट: एक उदाहरण के लिए याकूबकारबालो के उत्तर को देखें जो ओवरराइड करता है -[UITextField deleteBackward]

चेक आउट करें UITextInput, विशेष रूप UIKeyInputसे एक deleteBackwardप्रतिनिधि विधि है जो हमेशा डिलीट की दबाए जाने पर कॉल की जाती है। यदि आप कुछ सरल कर रहे हैं, तो आप बस उपवर्ग पर विचार कर सकते हैं UILabelऔर इसे UIKeyInputप्रोटोकॉल के अनुरूप बना सकते हैं , जैसा कि SimpleTextInput और इस iPhone UIKeyInput उदाहरण द्वारा किया गया है । नोट: UITextInputऔर इसके रिश्तेदार (सहित UIKeyInput) केवल iOS 3.2 और बाद में उपलब्ध हैं।


2
यह सही जवाब है। यह UITextField के एक त्वरित उपवर्ग के साथ गैर-हैकरी और बहुत सरल है।
सैम

बस नीचे दिए गए याकूब के जवाब को देखा। यह इसका विस्तृत उदाहरण देता है।
सैम

यह ध्यान देने योग्य है कि यह उत्तर iOS 5 में काम नहीं करता है। यदि पाठ फ़ील्ड खाली है तो बैकस्पेस इस विधि को लागू नहीं करता है।
जेफेलमैन

31

निम्नलिखित की तरह कोड:

@interface MyTextField : UITextField
@end

@implementation MyTextField

- (void)deleteBackward
{
    [super deleteBackward];

    //At here, you can handle backspace key pressed event even the text field is empty
}

@end

आखिर में, टेक्स्ट फील्ड की कस्टम क्लास प्रॉपर्टी को "MyTextField" में बदलना न भूलें


5
यह स्वीकृत उत्तर होना चाहिए। स्वच्छ, और वास्तव में प्रश्न का उत्तर देता है।
रयान रोमनचुक

1
यह प्रश्न का उत्तर देता है ... जब तक आप iOS 6.0+ को लक्षित कर रहे हैं। IOS 5 पर, डिलीटबैकवर्ड को कभी भी आपके उपवर्ग पर नहीं बुलाया गया, दुर्भाग्य से।
बीजे होमर

2
BJ Homer, 93% डिवाइस iOS 6 पर हैं, इसलिए iOS 5 को लक्षित नहीं करना आम तौर पर इतनी बड़ी बात नहीं है।
जोनाथन।

2
मुझे खुशी है कि मैंने इसे खोजने के लिए काफी नीचे स्क्रॉल किया। IOS 7. में आज ऐसा करने का 100% सही तरीका
MusiGenesis

मैंने इस प्रश्न के लिए बहुत सारे अन्य उत्तर देखे हैं जो सिर्फ वर्कअराउंड हैं, और शायद ही उनमें से कोई भी उस स्थिति से निपटता है जहां बैकस्पेस कुंजी को खाली क्षेत्र में दबाया जाता है। यह हालांकि एकदम सही है, और यह करने के लिए एक बहुत साफ तरीका है।
क्रिस्टोफर हन्ना

19

स्विफ्ट कार्यान्वयन:

import UIKit

protocol PinTexFieldDelegate : UITextFieldDelegate {
    func didPressBackspace(textField : PinTextField)
}

class PinTextField: UITextField {

    override func deleteBackward() {
        super.deleteBackward()

        // If conforming to our extension protocol
        if let pinDelegate = self.delegate as? PinTexFieldDelegate {
            pinDelegate.didPressBackspace(self)
        }
    }
}

धन्यवाद, क्या मुझे पता है कि यह विधि सेब द्वारा अनुशंसित है या यह हैक है। यह टेक्स्टफील्ड के लिए अनिर्दिष्ट लगता है।
कल्पेश जेटानी

मेरे लिए एक textView के साथ काम किया। साझा करने के लिए धन्यवाद;)
एडुआर्ड बारबियर

टेक्स्टफील्ड खाली होने और बैक स्पेस पर क्लिक करने पर मेरे लिए काम किया जाता है।
रामकृष्ण

17

मैंने subclassसमाधान की तुलना में आसान अन्य तरीके की स्थापना की है। यहां तक ​​कि यह थोड़ा अजीब है, लेकिन यह ठीक काम करता है।

- (BOOL)textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
        replacementText:(NSString *)text
{
    const char * _char = [text cStringUsingEncoding:NSUTF8StringEncoding];
    int isBackSpace = strcmp(_char, "\b");

    if (isBackSpace == -8) {
       // is backspace
    }

    return YES;
}

तुलना -8 के परिणाम के लिए यह थोड़ा अजीब है। शायद मैं किसी बिंदु पर गलत हूँ C Programming। लेकिन इसका सही काम;)


1
बैकस्ट्रोक सेट नहीं है। लेकिन अगर आप ध्यान से डिबगिंग करते हैं तो आप '\ 0' देखेंगे। तो मुझे परिणाम 0 मिलता है जो दो मान है जो strcmp विधि में बराबर हैं। const char * stoke = [पाठ cStringUsingEncoding: NSASCIIStringEncoding]; const char * backstroke = "\ 0"; // यह \ b -> "\ x08" के बराबर है; strcmp (बैकस्ट्रोक, स्टोक);
यूं ली

इसके अलावा, strcmp (s1, s2) की परिभाषा से, 0 रिटर्न अगर s1 == s2,> 0 s1 है, तो lexicographically s2 के विपरीत से बड़ा है।
यूं ली

मुझे समझ में नहीं आता कि यह संभवतः कैसे काम कर सकता है? @YoonLee: आप strcmpया तो रिटर्न नहीं कह रहे हैं -1, 0, or 1? यही मेरी समझ थी।
chug2k

1
टेक्स्टव्यू में आप हमेशा बैकस्पेस का पता लगाते हैं, भले ही कोई टेक्स्ट न हो, UITextField अलग है
LolaRun

2
यह एक UITextViewDelegateविधि है, नहीं UITextFieldDelegate
pkamb

11

की कोशिश delegate

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string {

फिर जांच करें कि हिट range.length == 1होने पर कौन सा मामला लगता है backspace


8
केवल तभी कहा जाता है जब क्षेत्र गैर-रिक्त हो, हालांकि। मूल प्रश्न पर ध्यान दें। :)
एरिक गोल्डबर्ग

इसके लिए UITextView का इस्तेमाल करें।
ओलेग

11

कृपया नीचे दिए गए कोड का उपयोग करें, इससे आपको टेक्स्ट डिलीट होने पर भी कीबोर्ड डिलीट की का पता लगाने में मदद मिलेगी।

उद्देश्य सी :

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; }

स्विफ्ट:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }

टीएक्स - बस मुझे क्या चाहिए। लेकिन यह कहाँ प्रलेखित है ??
एंडी वाइंस्टीन

9

निकलैस अल्वियस के उत्तर ने मुझे इसी तरह के मुद्दे के साथ मदद की

मैं एक विशिष्ट चरित्र सेट में प्रवेश को सीमित कर रहा था, लेकिन यह बैकस्पेस को अनदेखा कर रहा था। इसलिए मैंने इसे range.length == 1ट्रिम करने से पहले जांचा था NSString। अगर यह सच है, तो मैं स्ट्रिंग वापस करता हूं और इसे ट्रिम नहीं करता। निचे देखो

 - (BOOL) textField:(UITextField *)textField 
          shouldChangeCharactersInRange:(NSRange)range 
          replacementString:(NSString *)string
 {
     NSCharacterSet *nonNumberSet = 
      [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] 
         invertedSet];

    if (range.length == 1) {
       return string;
    }
    else {
       return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
    }   
 }

विधि एक बूलियन की उम्मीद करती है और वापसी मूल्य के रूप में एक स्ट्रिंग नहीं है
पास्कलियस

4

जैकब के उत्तर के बारे में जिन लोगों को समस्या है, मैंने निम्नलिखित के रूप में अपने टेक्स्टफील्ड उपवर्ग को लागू किया और यह बहुत अच्छा काम करता है!

#import <UIKit/UIKit.h>

@class HTTextField;

@protocol HTBackspaceDelegate <NSObject>

@optional
- (void)textFieldDidBackspace:(HTTextField*)textField;
@end

@interface HTTextField : UITextField<UIKeyInput>

@property (nonatomic, assign) id<HTBackspaceDelegate> backspaceDelegate;

@end


#import "HTTextField.h"

@implementation HTTextField

- (void)deleteBackward {
    [super deleteBackward];
    if ([self.backspaceDelegate respondsToSelector:@selector(textFieldDidBackspace:)]){
        [self.backspaceDelegate textFieldDidBackspace:self];
    }
}

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
    BOOL shouldDelete = YES;

    if ([UITextField instancesRespondToSelector:_cmd]) {
        BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];

        if (keyboardInputShouldDelete) {
            shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
        }
    }

    if (![textField.text length] && [[[UIDevice currentDevice] systemVersion] intValue] >= 8) {
        [self deleteBackward];
    }

    return shouldDelete;
}

@end

क्या आप स्विफ्ट के लिए कोड लिख सकते हैं। मुझे कुछ त्रुटि मिली "निरर्थक पुष्टिकरण प्रोटोको यूइकिनपुट के लिए"
राज अग्रवाल

4

हाँ, बैकस्पेस का पता लगाने के लिए नीचे की विधि का उपयोग करें, जब टेक्स्टफिल्ड खाली हो।

जोड़ने की जरूरत है UITextFieldDelegate

yourTextField.delegate = self (आवश्यक है)

स्विफ्ट:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { 
    return true
}

उद्देश्य सी:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}

5
यह मेरे लिए भी फोन नहीं करता है। जब कोई ईवेंट होता है, तो सभी अन्य प्रतिनिधि विधियों को बुलाया जाता है।
हेमांग

शुक्रिया दोस्त .. आपने इसे याद किया। :)
एमएस।

@ McDonal_11 मुझे लगता है कि आप textfield.delegate = self of textfield सेट करना भूल गए हैं।
हिमांशु पडिया

मैंने सेट किया है। अन्य UITextField के प्रतिनिधि तरीके ठीक काम कर रहे हैं। यह अकेले काम नहीं कर रहा है। मुझे क्या याद है ??
मैकडोनल_11

3

बैकस्पेस का पता लगाने के लिए मैंने जो सबसे अच्छा उपयोग किया है वह यह पता लगा रहा है कि उपयोगकर्ता ने बैकस्पेस को खाली में दबाया है UITextField। उदाहरण के लिए, यदि आपके पास मेल ऐप में 'बबलड' प्राप्तकर्ता हैं, तो जब आप बैकस्पेस में आते हैं UITextField, तो यह अंतिम 'बब्बल' प्राप्तकर्ता का चयन करता है।

यह जैकब कारबालो के जवाब के समान तरीके से किया जा सकता है। जैकब के उत्तर में, यदि आपके UITextFieldपास बैकस्पेस मारने पर एक वर्ण बचा है, तब तक जब प्रतिनिधि संदेश प्राप्त होता है, तो UITextFieldवह पहले से ही खाली हो जाएगा, इसलिए आप backspaceसबसे अधिक एक अक्षर के साथ एक पाठ क्षेत्र पर प्रभावी ढंग से पता लगा रहे हैं ।

वास्तव में, यदि आप पता लगाने के लिए चाहते हैं backspaceएक पर UITextFieldबिल्कुल शून्य वर्ण (खाली) के साथ है, तो आप संदेश भेजना चाहिए delegateकरने के लिए कॉल करने से पहले super deleteBackward। उदाहरण के लिए:

#import "MyTextField.h"

//Text field that detects when backspace is hit with empty text
@implementation MyTextField

#pragma mark - UIKeyInput protocol
-(void)deleteBackward
{
  BOOL isTextFieldEmpty = (self.text.length == 0);
  if (isTextFieldEmpty) {
    if ([self.delegate 
         respondsToSelector:@selector(textFieldDidHitBackspaceWithEmptyText:)]) {

        [self.delegate textFieldDidHitBackspaceWithEmptyText:self];
        }
    }
    [super deleteBackward];
}
@end

ऐसे टेक्स्ट फ़ील्ड के लिए इंटरफ़ेस कुछ इस तरह दिखाई देगा:

@protocol MyTextFieldDelegate;

@interface MyTextField : UITextField
@property(nonatomic, weak) id<MyTextFieldDelegate> delegate;
@end

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
-(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField;
@end

2
इसके लिए iOS8 में काम करने के लिए (जहां एक बग है जो इस डेलिगेट मेथड को कभी नहीं बुलाया जाता है), कृपया इस उत्तर को देखें: stackoverflow.com/a/25862878/893101Ios8
pIkEL

2

IOS 6 में, डिलीटबेकवर्ड विधि को UITextField पर बुलाया जाता है, जब बैकस्पेस को दबाया जाता है, जिसमें फ़ील्ड खाली होने पर भी शामिल होता है। तो आप UITextField को उप-वर्ग कर सकते हैं और अपना स्वयं का डिलीटबैकवर्ड कार्यान्वयन (सुपर के रूप में अच्छी तरह से लागू कर सकते हैं) प्रदान कर सकते हैं।

मैं अभी भी iOS 5 का समर्थन कर रहा हूं, हालांकि मुझे एंड्रयू के जवाब और इसके संयोजन की आवश्यकता होगी।


1

:) केवल "बैकस्पेस का पता लगाएं" शीर्षक के लिए, जहां मैं उपयोग करता हूं UIKeyboardTypeNumberPad

मैं आज रात को भी उसी प्रश्न को पूरा करता हूं, और यह जानने के लिए मेरा कोड निम्नलिखित है:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string
{
    NSLog([NSString stringWithFormat:@"%d", [string length]]);
}

क्योंकि के साथ UIKeyboardTypeNumberPad , उपयोगकर्ता केवल नंबर या बैकस्पेस इनपुट कर सकता है, इसलिए जब स्ट्रिंग की लंबाई 0 होती है, तो यह बैकस्पेस कुंजी होना चाहिए।

आशा है ऊपर वाला कुछ मदद करेगा।


यह किसी भी कीबोर्ड प्रकार के साथ समान है।
ma11hew28

मैं इस विधि को अपने पाठ क्षेत्र पर कैसे करूं?
user230910

1

पाठ क्षेत्र में क्या बीई होगा या किस विशेष चरित्र को shouldChangeCharactersInRangeविधि में दर्ज किया गया है, यह जानने की कोशिश करने के बजाय , मैं निम्नलिखित करने का सुझाव दूंगा:

[self performSelector:@selector(manageSearchResultsDisplay) 
           withObject:nil 
           afterDelay:0];

यह आपको वर्तमान ऑपरेशन पूरा होने के बाद सीधे एक विधि को कॉल करने की अनुमति देता है। इसके बारे में क्या अच्छा है, जब तक यह पूरा नहीं हो जाता, तब तक संशोधित मूल्य पहले से ही होगा UITextField। उस बिंदु पर, आप बस इसकी लंबाई की जांच कर सकते हैं और / या जो वहां है उसके आधार पर मान्य कर सकते हैं।


1

उप-क्लासिंग UITextField ने iOS 8.3 पर मेरे लिए काम नहीं किया, डिलीटबैकवर्ड को कभी नहीं बुलाया गया।

यहां वह समाधान है जो मैंने उपयोग किया था, सभी iOS 8 संस्करणों पर काम करता है और अन्य iOS संस्करणों पर भी काम करना चाहिए

for textField in textFields {
            textField.text = " "
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        if string == "" && textField.text == " "   {
            // Do stuff here
            return false
        }
        return true
}

1

.H फ़ाइल में UIKeyInput प्रतिनिधि जोड़ें

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

if ([textField isEqual:_txtFirstDigit]) {

}else if([textField isEqual:_txtSecondDigit]) {
    [_txtFirstDigit becomeFirstResponder];

}else if([textField isEqual:_txtThirdDigit]) {
    [_txtSecondDigit becomeFirstResponder];

}else if([textField isEqual:_txtFourthDigit]) {
    [_txtThirdDigit becomeFirstResponder];
}
return YES;
}   

स्वरूपण में सुधार


1

मैंने मामूली सुधार के साथ समान समाधान लागू किया है जो मुझे बताएगा कि यदि पाठ क्षेत्र का कोई मूल्य है जबकि उपयोगकर्ता ने बैकस्पेस का दोहन किया है। यह मेरे मामले के लिए उपयोगी है जब मुझे बैकस्पेस दबाए जाने पर पाठ फ़ील्ड खाली होने पर मुझे केवल एक अन्य टेक्स्ट फ़ील्ड पर ध्यान देना चाहिए।

protocol MyTextFieldDelegate : UITextFieldDelegate {
    func textFieldDidDelete(textField: MyTextField, hasValue: Bool)
}

override func deleteBackward() {
    let currentText = self.text ?? ""
    super.deleteBackward()
    let hasValue = currentText.isEmpty ? false : true
    if let delegate = self.delegate as? MyTextFieldDelegate {
        delegate.textFieldDidDelete(textField: self, hasValue: hasValue)
    }
}

1

सबसे अधिक चिनार का उत्तर एक बात याद आ रही है - यह पता लगाने की क्षमता कि पाठ क्षेत्र खाली था या नहीं।

यह है कि, जब आप एक पाठ फ़ाइल उपवर्ग के डिलीटबैकवर्ड () विधि को ओवरराइड करते हैं, तो आपको अभी भी पता नहीं है कि पाठ क्षेत्र पहले से ही खाली था या नहीं। (पहले और बाद में deleteBackwards दोनों), textField.text!एक खाली स्ट्रिंग है:"" )

यहां मेरा सुधार है, हटाए जाने से पहले खालीपन की जांच के साथ।

1. एक प्रतिनिधि प्रोटोकॉल बनाएं जो UITextFieldDelegate का विस्तार करता है

protocol MyTextFieldDelegate: UITextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool)
}

2. उपवर्ग UITextField

class MyTextField: UITextField {
    override func deleteBackward() {
        // see if text was empty
        let wasEmpty = text == nil || text! == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

3. अपने नए प्रतिनिधि प्रोटोकॉल को लागू करें

extension MyViewController: MyTextFieldDelegate {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        if wasEmpty {
            // do what you want here...
        }
    }
}

1

स्विफ्ट 5.1 के लिए एकल अंक संख्या के साथ टेक्स्टफील्ड के लिए व्यापक हैंडलर :

  • यह मानते हुए कि आपके पास टेक्स्टफ़िल्ड का आउटलेट संग्रह है (जुड़े प्रतिनिधियों के साथ)

1 स्टेप

protocol MyTextFieldDelegate: class {
    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) 
}

final class MyTextField: UITextField {

    weak var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        let wasEmpty = text == nil || text == ""

        // then perform normal behavior
        super.deleteBackward()

        // now, notify delegate (if existent)
        (delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
    }
}

2 स्टेप

final class ViewController: UIViewController {

    @IBOutlet private var textFields: [MyTextField]!

    override func viewDidLoad() {
        super.viewDidLoad()
        textFields.forEach {
            $0.delegate = self
            $0.myDelegate = self
        }
    }
}

3 स्टेप

extension ViewController: UITextFieldDelegate, MyTextFieldDelegate {
    func textFieldHasChanged(with text: String, _ tag: Int, for textField: UITextField) {
        textField.text = text

        if let someTextField = (textFields.filter { $0.tag == tag }).first {
            someTextField.becomeFirstResponder()
        } else {
            view.endEditing(true)
        }
    }

    func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool) {
        // If the user was pressing backward and the value was empty, go to previous textField
        textFieldHasChanged(with: "", textField.tag - 1, for: textField)
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // Restrict to only digits
        let aSet = NSCharacterSet(charactersIn: "0123456789").inverted
        let compSepByCharInSet = string.components(separatedBy: aSet)
        let numberFiltered = compSepByCharInSet.joined(separator: "")

        guard string == numberFiltered, let text = textField.text else { return false }

        if text.count >= 1 && string.isEmpty {
            // If the user is deleting the value
            textFieldHasChanged(with: "", textField.tag - 1, for: textField)
        } else {
            textFieldHasChanged(with: string, textField.tag + 1, for: textField)
        }

        return false
    }
}

0

यहाँ मेरा समाधान @ विचार पर आधारित है:

कहीं न कहीं, उदाहरण के लिए viewDidLoad में

        textField.delegate = self
        textField.addTarget(self, action: #selector(valueChanged(_:)), for: .editingDidBegin)

और फिर

    @objc func valueChanged(_ textField: UITextField) {
        textField.text = "\u{200B}"
    }

    override func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        textField.text = string
        if string == "" {
            //backpaspace pressed 
        }

0

आप पाठ दृश्य / फ़ील्ड के पाठ की जांच कर सकते हैं कि क्या यह खाली है और सुनिश्चित करें कि प्रतिस्थापन पाठ को shouldChangeTextIn प्रतिनिधि विधि में भी खाली है।

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if (textView.text == "" && text == "") {
        print("Backspace on empty text field.")
    }
    return true
}

-2

कुछ इस तरह:

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string       
{  
    if (![text hash] && ![textField.text length])  
        [self backspaceInEmptyTextField];  
}

बेशक हैश एक वर्ण स्ट्रिंग के लिए है।


-2

TextField प्रतिनिधि विधि का उपयोग:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

डिलीट इवेंट का पता लगाने के लिए उपरोक्त विधि में निम्न कोड जोड़ें

if(textField == YourTextField)
{
    if ([string length] == 0 && range.length > 0)
    {
        // Your Code after deletion of character
    }
}

-3

इसे सरल रखने के लिए यहाँ केवल वही स्थिति है जो आपको जाँचने की आवश्यकता है

     if (range.length==1)

-3
+ (BOOL)detectBackspaceOnly:(NSString *)string
{
    for(int i=0 ; i<string.length ; i++){
        unichar caract = [string characterAtIndex:i];
        if(caract != ' ' && caract != '\n')
            return NO;
    }

    return YES;
}

2
शायद थोड़ा स्पष्टीकरण जहां यह डाल करने के लिए?
एलेक्स Cio

-4

इन UITextViewDelegate:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if(text isEqualToString:@"");
    {
        NSLog(@"press backspace.");
    }
}

यह मेरे लिए ठीक काम करता है।

चीनी सरलीकृत पिनयिन और चीनी लिखावट इनपुट के लिए अद्यतन:

- (BOOL)               textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
                replacementText:(NSString *)text
{
    if (range.length > 0 && [text isEqualToString:@""]) {
        NSLog(@"press Backspace.");
    }
    return YES;
}

दस्तावेज के आधार पर कहते हैं:

"यदि उपयोगकर्ता दबाता है deleteKey, तो सीमा की लंबाई 1 है और एक खाली स्ट्रिंग ऑब्जेक्ट उस एकल वर्ण को बदल देता है।"


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