Search code examples
swiftuitextfielduitextfielddelegate

How to format a textfield so when user inputs data its in format similar to 80/150?


Currently there is a textfield that after a user enters data it has to post to a server in a format similar to 60/500, so basically a fraction. I'm familiar with setting up a textfield and connecting it via storyboard along with setting up text input traits so the number pad will show up. I'm just not sure how to change the entered textfield into the '30/90' fraction format and posting it. Any help will be greatly appreciated!


Solution

  • You could do it this way, after setting self as the delegate:

    let slash = "/"
    let digits = CharacterSet(charactersIn: "0123456789")
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
        //Deleting
        if string.count == 0 {
            var text = textField.text!
            let start = text.startIndex
            let beginRange = text.index(start, offsetBy: range.location)
            let endRange = text.index(start, offsetBy: range.location + range.length)
            text = String(text.prefix(upTo: beginRange))
                + String(text.suffix(from: endRange))
            text = text.replacingOccurrences(of: "/", with: "")
            if text.count >= 3 {
                text = String(text.prefix(2)) + "/" + String(text.dropFirst(2))
            }
    
            textField.text = text
    
            return false
        }
    
        //Typing
    
        let count = textField.text!.count
        guard string.count == 1,
            count < 6,
            let scalar = Character(string).unicodeScalars.first else {
                return false
        }
    
        let isDigit = digits.contains(scalar)
    
        switch count {
        case 0, 3..<6 :
            return isDigit
        case 1:
            if isDigit {
                textField.text = textField.text! + string + "/"
            }
            return false
        case 2:
            if string == slash {
                return true
            } else {
                textField.text = textField.text! + "/" + string
                return false
            }
        default:
            return false
        }
    }
    

    This code works with the default keyboard too, and not just the numeric pad.