UITextField format in xx-xx-xxx

后端 未结 10 1626
暖寄归人
暖寄归人 2020-11-27 04:13

I am using UITextField and i want that should take character in the format of xx-xx-xxx only numbers.

any help ?

相关标签:
10条回答
  • 2020-11-27 04:38

    If you want it to be something like a date then you can make your own date formatter like this:

    NSDateFormatter *formatter;
    NSString        *dateString;
    
    formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"dd-MM-yyyy HH:mm"]; //or something in your own style
    
    dateString = [formatter stringFromDate:[NSDate date]];
    
    [formatter release];  // maybe; you might want to keep the formatter 
                          // if you're doing this a lot.
    

    Getting Current Time in string in Custom format in objective c

    0 讨论(0)
  • 2020-11-27 04:39

    Swift kind of long method but works fine: iOS 8

    ViewController // programming mark ----- ----- ---- ----- ----- ---- ----- ----- ----

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    
        self.tfCardNumber.addTarget(self, action: "creditCardNumberFormatter:", forControlEvents: .EditingChanged)
        self.tfExpiryValue.addTarget(self, action: "creditCardExpiryFormatter:", forControlEvents: .EditingChanged)
    
    }// end viewDidAppear
    
      func creditCardNumberFormatter(sender: AnyObject!) {
    
        // create object universally access global methods
        var objMethodInc = MethodInc(object: self)
    
        var formattedText = objMethodInc.formatCreditCard(self.tfCardNumber.text)
    
        if formattedText != self.tfCardNumber.text {
    
            self.tfCardNumber.text = formattedText
    
        }
    
        if countElements(self.tfCardNumber.text) == 19 {
    
            self.tfCardNumber.resignFirstResponder()
            self.tfExpiryValue.becomeFirstResponder()
    
        }
    
    
    }// end creditCardNumberFormatter
    
    func creditCardExpiryFormatter(sender: AnyObject!) {
    
        // create object universally access global methods
        var objMethodInc = MethodInc(object: self)
    
        var formattedText = objMethodInc.formatCreditCardExpiry(self.tfExpiryValue.text)
    
        if formattedText != self.tfExpiryValue.text {
    
            self.tfExpiryValue.text = formattedText
    
        }
    
    }// end creditCardExpiryFormatter
    

    // prgm mark --- ---- --- ----

    // delegate for textfield
    
    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange
        , replacementString string: String) -> Bool {
    
        if string == "" {
            return true
        }
    
        if textField == self.tfCardNumber {
    
            if countElements(self.tfCardNumber.text) > 18 {
    
                return false
    
            } else if textField == self.tfExpiryValue {
    
                if countElements(self.tfExpiryValue.text) > 4 {
                    return false
                }
    
            }
        }
    
        return true
    
    }// end textField
    

    ----------- INSIDE your command method or file --------

    // prgm mark ----

    func formatCreditCard(input: NSString) -> String {
    
        var input = self.trimSpecialCharacters(input);
    
        println("formatCreditCard input \(input)")
    
        var output : NSString?
    
        switch (input.length) {
    
        case 1: output = input
        case 2: output = input
        case 3: output = input
        case 4:
            var vs = input.substringToIndex(input.length)
            output = NSString(string: "\(vs)")
            break
    
        case 5: output = input
        case 6: output = input
        case 7: output = input
        case 8:
            var vs1 = input.substringToIndex(4)
            var vs2 = input.substringFromIndex(4)
            output = NSString(string: "\(vs1)-\(vs2)")
            break
    
        case 9: output = input
        case 10: output = input
        case 11: output = input
    
        case 12:
            var vs1 = input.substringToIndex(4)
            var vs2 = input.substringWithRange(NSMakeRange(4, 4))
            var vs3 = input.substringFromIndex(8)
            output = NSString(string: "\(vs1)-\(vs2)-\(vs3)")
            break
    
        case 13: output = input
        case 14: output = input
        case 15: output = input
        case 16:
            var vs1 = input.substringToIndex(4)
            var vs2 = input.substringWithRange(NSMakeRange(4, 4))
            var vs3 = input.substringWithRange(NSMakeRange(8, 4))
            var vs4 = input.substringFromIndex(12)
            output = NSString(string: "\(vs1)-\(vs2)-\(vs3)-\(vs4)")
            break
        default:
            output = input
            break
    
        }//  end switch
    
        println("formatCreditCard out \(output!)")
    
        return output!
    
    }// end  formatCreditCard
    
    
    // prgm mark ----
    
    func formatCreditCardExpiry(input: NSString) -> String {
    
        var output : NSString?
    
        var input = self.trimSpecialCharacters(input);
    
        switch (input.length) {
    
        case 1: output = input
        case 2:
            var vs = input.substringToIndex(input.length)
            output = NSString(string: "\(vs)")
            break
    
        case 3: output = input
        case 4:
            var vs1 = input.substringToIndex(2)
            var vs2 = input.substringFromIndex(2)
            output = NSString(string: "\(vs1)/\(vs2)")
            break
        default:
            output = input
            break
        }
    
        return output!
    
    }// end  formatCreditCardExpiry
    
    
    func trimSpecialCharacters(input: NSString) -> NSString {
    
        var special = NSCharacterSet(charactersInString: "/+-() ")
    
        var comp = input.componentsSeparatedByCharactersInSet(special) as NSArray
    
        return comp.componentsJoinedByString("")
    
    }//end trimSpecialCharacters
    
    0 讨论(0)
  • 2020-11-27 04:44

    My google searches tell me that you should implement

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

    from the UITextFieldDelegate protocol.

    Have a look at this for more info.

    0 讨论(0)
  • 2020-11-27 04:45

    Here is my take on it after looking at everyone's answers.

    Swift 4

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let separator = "-"
        let filler = "X"
        if var number = textField.text, string != "" {
            number = number.replacingOccurrences(of: separator, with: "")
            number = number.replacingOccurrences(of: filler, with: "")
            if number.count == 10 { return false }
            number += string
            while number.count < 10 { number += "X" }
            number.insert("-", at: number.index(number.startIndex,
                                                offsetBy: 6))
            number.insert("-", at: number.index(number.startIndex,
                                                offsetBy: 3))
            textField.text = number
        }
        return false
    }
    
    0 讨论(0)
  • 2020-11-27 04:49

    My solution works like that:

    Implement in your textfield delegates:

    func textFieldDidBeginEditing(_ textField: UITextField) {
            // When you start editing check if there is nothing, in that case add the entire mask
            if let text = textField.text, text == "" || text == "DD/MM/YYYY" {
                textField.text = "DD/MM/YYYY"
                textField.textColor = .lightGray
                textField.setCursor(position: text.count)
            }
        }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        guard var number = textField.text else {
            return true
        }
        // If user try to delete, remove the char manually
        if string == "" {
            number.remove(at: number.index(number.startIndex, offsetBy: range.location))
        }
        // Remove all mask characters
        number = number.replacingOccurrences(of: "/", with: "")
        number = number.replacingOccurrences(of: "D", with: "")
        number = number.replacingOccurrences(of: "M", with: "")
        number = number.replacingOccurrences(of: "Y", with: "")
    
        // Set the position of the cursor
        var cursorPosition = number.count+1
        if string == "" {
            //if it's delete, just take the position given by the delegate
            cursorPosition = range.location
        } else {
            // If not, take into account the slash
            if cursorPosition > 2 && cursorPosition < 5 {
                cursorPosition += 1
            } else if cursorPosition > 4 {
                cursorPosition += 2
            }
        }
        // Stop editing if we have rich the max numbers
        if number.count == 8 { return false }
        // Readd all mask char
        number += string
        while number.count < 8 {
            if number.count < 2 {
                number += "D"
            } else if number.count < 4 {
                number += "M"
            } else {
                number += "Y"
            }
        }
        number.insert("/", at: number.index(number.startIndex, offsetBy: 4))
        number.insert("/", at: number.index(number.startIndex, offsetBy: 2))
    
        // Some styling
        let enteredTextAttribute = [NSForegroundColorAttributeName: UIColor.black, NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
        let maskTextAttribute = [NSForegroundColorAttributeName: UIColor.lightGray, NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
    
        let partOne = NSMutableAttributedString(string: String(number.prefix(cursorPosition)), attributes: enteredTextAttribute)
        let partTwo = NSMutableAttributedString(string: String(number.suffix(number.count-cursorPosition)), attributes: maskTextAttribute)
    
        let combination = NSMutableAttributedString()
    
        combination.append(partOne)
        combination.append(partTwo)
    
        textField.attributedText = combination
        textField.setCursor(position: cursorPosition)
    
    
        return false
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        if let text = textField.text, text != "" && text != "DD/MM/YYYY" {
            // Do something with your value
        } else {
            textField.text = ""
        }
    }
    

    And that little helper as an extension:

    extension UITextField {
        func setCursor(position: Int) {
            let position = self.position(from: beginningOfDocument, offset: position)!
            selectedTextRange = textRange(from: position, to: position)
        }
    }
    

    PS: there is still a bug in that implementation when you try to move the cursor while editing

    0 讨论(0)
  • 2020-11-27 04:50

    This worked for me after a little bit of customization from one of the answers.

    extension String {
        func applyPatternOnNumbers(pattern: String, filler: Character) -> String {
            var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
            // Insert filler for all occurances of filler in pattern
            for index in pattern.indices {
                print(pattern[index])
                let patternChar = pattern[index]
                if patternChar == filler {
                    if index <= pureNumber.endIndex {
                        pureNumber.insert(filler, at: index)
                    }
                }
            }
            return pureNumber
        }
    }
    

    Usage:

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if(text == "\n") {
            textView.resignFirstResponder()
            return false
        } else if !text.isEmpty {
            guard let text = textView.text else { return true }
            textView.text = text.applyPatternOnNumbers(pattern: "###-##-####", filler: "-")
        }
        return true
    }
    
    0 讨论(0)
提交回复
热议问题