UITextField इनपुट के लिए केवल नंबर की अनुमति दें


82

IPad में iPhone / iPod की तरह "Numpad" कीबोर्ड नहीं है।

मैं खोजने के लिए देख रहा हूं कि मैं उपयोगकर्ता के कीबोर्ड को केवल 9 के माध्यम से मानों को स्वीकार करने के लिए कैसे प्रतिबंधित कर सकता हूं।

मैं UITextField के "shouldChangeCharactersInRange" का उपयोग करने की कल्पना करूंगा, लेकिन मुझे इसे लागू करने का सबसे अच्छा तरीका नहीं पता है।


मैंने डाउनलोड करने योग्य प्रोजेक्ट सोर्स कोड के साथ इसे पूरा करने के बारे में एक ट्यूटोरियल बनाया। यहाँ: xcodenoobies.blogspot.com/2013/12/…
GeneCode

जवाबों:


86

यह है कि आप एसएसएन सत्यापन क्षेत्र पर समस्या को कैसे संभाल सकते हैं, आप अधिकतम लंबाई को संशोधित कर सकते हैं और ifयदि आवश्यक हो तो कीबोर्ड प्रकार के लिए विवरण की जाँच कर सकते हैं।

जब उपयोगकर्ता डेटा चिपकाने के विपरीत टाइप कर रहा हो तो अधिकतम लंबाई अलर्ट को दबाने का तर्क भी है।

इस कोड के संदर्भ में, presentAlert()/presentAlert:केवल कुछ मूल फ़ंक्शन हैं जो पास किए गए संदेश स्ट्रिंग का उपयोग करके UIAlertController(या विरासत UIAlertView) प्रस्तुत करता है ।

स्विफ्ट 5

// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the 
// object that will contain this code, because otherwise it would never be called.
//
// There are also some better stylistic approaches in Swift to avoid all the 
// nested statements, but I wanted to keep the styles similar to allow others 
// to contrast and compare between the two languages a little easier.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // Handle backspace/delete
    guard !string.isEmpty else {

        // Backspace detected, allow text change, no need to process the text any further
        return true
    }

    // Input Validation
    // Prevent invalid character input, if keyboard is numberpad
    if textField.keyboardType == .numberPad {

        // Check for invalid input characters
        if CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) {

            // Present alert so the user knows what went wrong
            presentAlert("This field accepts only numeric entries.")

            // Invalid characters detected, disallow text change
            return false
        }
    }

    // Length Processing
    // Need to convert the NSRange to a Swift-appropriate type
    if let text = textField.text, let range = Range(range, in: text) {

        let proposedText = text.replacingCharacters(in: range, with: string)

        // Check proposed text length does not exceed max character count
        guard proposedText.count <= maxCharacters else {

            // Present alert if pasting text
            // easy: pasted data has a length greater than 1; who copy/pastes one character?
            if string.count > 1 {

                // Pasting text, present alert so the user knows what went wrong
                presentAlert("Paste failed: Maximum character count exceeded.")
            }

            // Character count exceeded, disallow text change
            return false
        }

        // Only enable the OK/submit button if they have entered all numbers for the last four
        // of their SSN (prevents early submissions/trips to authentication server, etc)
        answerButton.isEnabled = (proposedText.count == 4)
    }

    // Allow text change
    return true
}

उद्देश्य सी

// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the 
// object that will contain this code, because otherwise it would never be called.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    // Handle backspace/delete
    if (!string.length)
    {
        // Backspace detected, allow text change, no need to process the text any further
        return YES;
    }

    // Input Validation
    // Prevent invalid character input, if keyboard is numberpad
    if (textField.keyboardType == UIKeyboardTypeNumberPad)
    {
        if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound)
        {
            [self presentAlert: @"This field accepts only numeric entries."];
            return NO;
        }
    }

    // Length Validation
    NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];

    // Check proposed text length does not exceed max character count
    if (proposedText.length > maxCharacters)
    {
        // Present alert if pasting text
        // easy: pasted data has a length greater than 1; who copy/pastes one character?
        if (string.length > 1)
        {
            // Pasting text, present alert so the user knows what went wrong
            [self presentAlert: @"Paste failed: Maximum character count exceeded."];
        }

        // Character count exceeded, disallow text change
        return NO;
    }

    // Only enable the OK/submit button if they have entered all numbers for the last four
    // of their SSN (prevents early submissions/trips to authentication server, etc)
    self.answerButton.enabled = (proposedText.length == maxCharacters);

    // Allow text change
    return YES;
}

2
धन्यवाद! इनपुट से अमान्य वर्ण हटाएं, यदि कीबोर्ड नंबरपैड है 'अनुभाग ने मेरे प्रश्न का उत्तर देने में मदद की!
डेमस्टरप्ल

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

पहले से ही इसका इस्तेमाल किया है, लेकिन यह प्रमुख
जीरो के

@Gargo आप अन्य अवधि वर्णों का पता लगाने के लिए उसके पास कुछ समान का उपयोग कर सकते हैं और केवल एक शून्य वर्ण के लिए हाँ वापस कर सकते हैं यदि: पाठ फ़ील्ड वर्तमान में खाली है, यदि प्रविष्टि बिंदु इंडेक्स 0 पर है और अगला वर्ण एक अवधि है, या यदि सम्मिलन बिंदु मौजूदा अवधि वर्ण की तुलना में अधिक सूचकांक पर है। कम से कम यह एक तरीका होगा जिससे मैं यह सुनिश्चित कर सकता हूं कि दर्ज किया जा रहा शून्य एक अग्रणी शून्य समस्या पैदा नहीं करेगा।
बेलतालोवाड़ा

26

आप टेक्स्ट कोड में केवल संख्या की अनुमति देने के लिए इस कोड का उपयोग कर सकते हैं।

इससे पहले textField के लिए प्रतिनिधि सेट करें

      textFieldName.delegate=self;

या

      [textFieldName setDelegate:self];

इस कोड का उपयोग केवल टेक्स्टफिल्ड के लिए अंक की अनुमति देने के लिए करें

      - (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string {
//return yes or no after comparing the characters

      // allow backspace
      if (!string.length)
      {
           return YES;
      }

      ////for Decimal value start//////This code use use for allowing single decimal value
      //    if ([theTextField.text rangeOfString:@"."].location == NSNotFound)
      //    {
      //        if ([string isEqualToString:@"."]) {
      //            return YES;
      //        }
      //    }
      //    else
      //    {
      //        if ([[theTextField.text substringFromIndex:[theTextField.text rangeOfString:@"."].location] length]>2)   // this allow 2 digit after decimal 
      //        {
      //            return NO;
      //        }
      //    }
      ////for Decimal value End//////This code use use for allowing single decimal value

      // allow digit 0 to 9
      if ([string intValue])
      {
            return YES;
      }

      return NO;
    }

5
btw, इस कोड का उपयोग करने वाले अन्य लोगों के [string intValue]लिए, @ "0" के लिए 0 लौटाता है - इसलिए if ([string intValue])@ "0" के लिए नहीं मिला है। बेहतर उपयोग करने के लिएif ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
चार्ल्स

2
@".".intValueहै 0. और @"0".intValue0 भी है।
6

यहां अन्य टिप्पणियों को स्पष्ट करने के लिए: यह कोड उपयोगकर्ता को शून्य ( 0) वर्ण टाइप नहीं करने देता ।
बेल्‍टलोव्‍डा

23

पाठ्यक्षेत्र समाशोधन मुद्दे से बचने के लिए यह प्रयास करें

स्विफ्ट 3.0

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    guard NSCharacterSet(charactersInString: "0123456789").isSupersetOfSet(NSCharacterSet(charactersInString: string)) else {
        return false
    }
    return true
}

स्विफ्ट 4.0

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
        return false
    }
    return true
}

2
आप प्रतिनिधि विधि को सरल बना सकते हैं और बस छोड़ दिया जा सकता हैreturn guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string))
हैमस्टर्निक

मैंने अपने कोड पर कॉपी और पेस्ट किया और काम नहीं किया। मैं इसे कैसे कनेक्ट करूं और इसे काम करूं?
यश जैन

पहला सेट टेक्स्टफिल्ड प्रतिनिधि (textField.delegate = self) और UITextFieldDelegate प्रोटोकॉल के अनुरूप है।
एसपीटेल

19

स्विफ्ट कोड के लिए बहुत विशिष्ट कदम

आप तर्क प्रदान कर सकते हैं func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Boolजो UITextFieldDelegateप्रोटोकॉल को लागू करके विधि में पाठ क्षेत्र के इनपुट को प्रतिबंधित करता है।

स्पष्टता के लिए, ये चरण मानते हैं कि आपके स्टोरीबोर्ड में एक टेक्स्ट फ़ील्ड ऑब्जेक्ट के साथ व्यू कंट्रोलर है जिसमें केवल अंकों को स्वीकार करना चाहिए।

  1. व्यू कंट्रोलर के लिए एक कस्टम क्लास बनाएँ जो फैली हुई हो UIViewControllerसुनिश्चित करें कि आपके स्टोरीबोर्ड में दृश्य एक्सकोड की पहचान निरीक्षक में कस्टम वर्ग मान सेट करके कस्टम वर्ग को संदर्भित करता है।

    import UIKit
    class YourCustomController: UIViewController {
        override func viewDidLoad() {        
            super.viewDidLoad()
        }
    }
    
  2. अपने दृश्य के टेक्स्ट फ़ील्ड से अपने कस्टम व्यू कंट्रोलर तक एक आउटलेट बनाएं।

    class YourCustomController: UIViewController {
        @IBOutlet weak var numberField: UITextField!
        ...
    }
    
  3. UITextFieldDelegateअपने कस्टम व्यू कंट्रोलर में प्रोटोकॉल लागू करें ।

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
    }
    
  4. अपने कस्टम व्यू कंट्रोलर की viewDidLoadविधि में, अपने कस्टम व्यू कंट्रोलर क्लास को अपने टेक्स्ट फील्ड के डेलीगेट को असाइन करें।

    override func viewDidLoad() {        
        super.viewDidLoad()
        numberField.delegate = self
    }
    
  5. जोड़े UITextFieldDelegateकी func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Boolविधि।

    अपने कस्टम दृश्य नियंत्रक को numberFieldपिछले चरण में प्रतिनिधि बनाने के परिणामस्वरूप , यह विधि प्रत्येक बार उपयोगकर्ता को पाठ क्षेत्र में एक चरित्र में प्रवेश करने के लिए कहा जाएगा। यदि आपकी विधि वापस आती है trueतो चरित्र पाठ क्षेत्र में बना रहेगा। यदि आपकी विधि वापस आती है falseतो चरित्र पाठ क्षेत्र में नहीं रहेगा।

    stringपैरामीटर चरित्र उपयोगकर्ता द्वारा दर्ज की जा रही है। यदि stringचरित्र को एक में परिवर्तित किया जा सकता है, Intतो यह 0 और 9 के बीच है; अन्यथा, यह कुछ गैर-संख्या वर्ण है।

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
            return Int(string) != nil
        }
    }
    

(पूर्ण दृश्य नियंत्रक कोड के लिए नीचे देखें।)


उदाहरण केवल पाठ क्षेत्र के अंकों के साथ नियंत्रक देखें

import UIKit

class YourCustomController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var numberField: UITextField!

    override func viewDidLoad() {        
        super.viewDidLoad()       
        numberField.delegate = self
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {        
        return Int(string) != nil
    }    
}

उदाहरण दृश्य नियंत्रक एक दशमलव पाठ फ़ील्ड के साथ

यदि आप दशमलव संख्या का समर्थन करना चाहते हैं तो लाभ उठाएँ NSNumberFormatter। अंतर के लिए कोड टिप्पणी देखें।

import UIKit

class YourCustomController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var numberField: UITextField!

    private var formatter: NSNumberFormatter!

    override func viewDidLoad() {        
        super.viewDidLoad()       
        numberField.delegate = self

        // Initialize the formatter; minimum value is set to zero; style is Decimal. 
        formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
        formatter.minimum = 0
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        // Combine the current text field value and the new string
        // character. If it conforms to the formatter's settings then
        // it is valid. If it doesn't then nil is returned and the
        // string character should not be allowed in the text field.         
        return formatter.numberFromString("\(textField.text)\(string)") != nil
    }    
}

3
यह अच्छा है, लेकिन एक छोटा सा समायोजन किया है क्योंकि यह आपको खाली स्ट्रिंग के लिए चेक के बिना क्षेत्र में कुछ भी हटाने की अनुमति नहीं देता है। मैंने पहले चरित्र की जाँच करके नकारात्मक के लिए क्षमता भी जोड़ी है अगर (string == "-" && range.location == 0) || string == "" {वापसी सच} वापसी string.toInt ()! = nil
ickydime

return string.toInt() != nil एक जादू की तरह काम किया। धन्यवाद!
कैलजोन

नोट स्विफ्ट 2 में मुझे इसे बदलना पड़ाreturn Int(string) != nil
नेवस्टर

@nevster टिप्पणी के लिए धन्यवाद! मुझे लगता है कि अधिकांश स्विफ्ट डेवलपर्स स्थानांतरित हो गए हैं या स्विफ्ट 2 और इसके बाद के संस्करण पर जा रहे हैं। इसलिए, मैंने स्विफ्ट 2 के स्ट्रिंग-टू-इंट रूपांतरण के अनुरूप उत्तर को अपडेट किया।
Whyceewhite

7
एक और बदलाव मुझे करना पड़ा - डिलीट की अब काम नहीं किया! इसलिए मैंने इसे बदल दियाreturn string == "" || Int(string) != nil
नेवस्टर

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

    NSNumberFormatter * nf = [[NSNumberFormatter alloc] init];
    [nf setNumberStyle:NSNumberFormatterNoStyle];

    NSString * newString = [NSString stringWithFormat:@"%@%@",textField.text,string];
    NSNumber * number = [nf numberFromString:newString];

    if (number)
        return YES;
    else
       return NO;
}

1
यह अंश के लिए ठीक काम करता है, बस आपको सही न्यूस्ट्रिंग बदलने की आवश्यकता है: NSString * newString = [textField.text stringByReplacingCharactersInRange: रेंज withString: string];
इडली

7

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

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
// Check for non-numeric characters
NSUInteger lengthOfString = string.length;
for (NSInteger index = 0; index < lengthOfString; index++) {
    unichar character = [string characterAtIndex:index];
    if (character < 48) return NO; // 48 unichar for 0
    if (character > 57) return NO; // 57 unichar for 9
}
// Check total length for restrict user
NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
if (proposedNewLength > 6)
    return YES;
return YES;                                                                                                                                     
}

1
"जोड़ने के लिए।", के if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9साथ बदलें if ((character < 48 || character > 57) && character != 46)मैं आपको अतिरिक्त characterरूप से संख्याओं के एक हेक्साडेसिमल निरूपण की तुलना करने की सलाह दूंगा क्योंकि हेक्साडेसिमल इन परिस्थितियों में सबसे अधिक उपयोग किए जाते हैं। Ieif ((character < 0x30 || character > 0x39) && character != 0x2E)
जैकब आर

2
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
    if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
        return NO;
    }

2
Works fine for me :

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound) && !(range.length==1 && string.length==0)) {
            return NO;
        }
        return YES;
    }

1

स्विफ्ट में:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return string.isEmpty || Int(string) != nil
    }

1

तेज ५

    //MARK:- UITextFieldDelegate

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let allowedCharacters = "1234567890"
    let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters)
    let typedCharcterSet = CharacterSet(charactersIn: string)
    return allowedCharcterSet.isSuperset(of: typedCharcterSet)
}

अब आप केवल 1234567890 पर टैप कर सकते हैं


आप इसे कैसे लागू करते हैं? बस इस फ़ंक्शन को बनाने से यह UITextfield
यश जैन

0

आंतरिक प्रस्तुति से अलग प्रस्तुति डेटा रखें। एक सरल तरीका है। NSNumberFormatterकाम करने दो :

 NSNumberFormatter* ns = [[NSNumberFormatter alloc] init];
 ns.numberStyle = NSNumberFormatterDecimalStyle;
 [ns setMaximumFractionDigits:2];
 // This is your internal representation of the localized number
 double a = [[ns numberFromString:self.textIVA.text] doubleValue]];

[mylabel setText:[NSString stringWithFormat:@"€ %@",
     [NSNumberFormatter localizedStringFromNumber:
                          [NSNumber numberWithDouble:a]
                                      numberStyle:NSNumberFormatterDecimalStyle]]];

0

यदि आप मेरे विनिर्देशन पैटर्न का उपयोग करते हैं तो कोड इस तरह दिखता है

textField.delegate = self

lazy var specification: Specification = {
    return RegularExpressionSpecification(pattern: "^(|0|[1-9]\\d{0,6})$")
}()

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let textFieldString: NSString = textField.text ?? ""
    let s = textFieldString.stringByReplacingCharactersInRange(range, withString:string)
    return specification.isSatisfiedBy(s)
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let s = textField.text ?? ""
    let isTextValid = specification.isSatisfiedBy(s)
    if isTextValid {
        textField.resignFirstResponder()
    }
    return false
}

मैं UITextfield को केवल नंबर प्राप्त करने और 6 और 8 के बीच संख्याओं की मात्रा को सीमित करने के लिए कैसे प्रतिबंधित करूंगा?
मार्को अल्मेडा

Hi @MarcoAlmeida मेरे ढांचे SwiftyFORM पर एक नज़र डालें, यह मान्य पाठ, github.com/neoneye/SwiftyFORM
neoneye

0

मैंने अंकों के लिए काम करने के लिए @ iDev के उत्तर को संशोधित किया है और "।":

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
     // Check for non-numeric characters
     NSUInteger lengthOfString = string.length;
     for (NSInteger index = 0; index < lengthOfString; index++) {
         unichar character = [string characterAtIndex:index];
         if ((character < 48) && (character != 46)) return NO; 
         // 48 unichar for 0, and 46 unichar for point
         if (character > 57) return NO; 
         // 57 unichar for 9
     }
     // Check for total length
     NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
     if (proposedNewLength > 6)
         return YES;
     return YES; 
 }

0

स्विफ्ट 3

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField==yourTextFieldOutlet {
                if(CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: yourTextFieldOutlet.text!))){
//if numbers only, then your code here
                }
                else{
                showAlert(title: "Error",message: "Enter Number only",type: "failure")
                }
            }
    return true
    }

-1

इस कोड का उपयोग करें:

NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
    return NO;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.