Formatting values as HH:MM on uiTextField

Dears,


How can I format the values as HH:MM on uiTextField?

The user may not be able to enter any other value different from HH:MM... He/she doesn't even need to enter the ":" value... all he/she needs to enter is the values of HH and MM... It's a 24h interval... so the accepted values are from 00:00 up to 23:59.


How can I do it?

Thank you

Accepted Reply

You have 2 ways :

a- wait till the user has completed the textField and hit return to test the content is correct

b- test after each key press that format is correct.


In anycase, the most effective would be to use a regular expression to test, but if yopu prefer to do it manually, can do this:


For case a, connect the UITextField sentMessages "DidEndOnExit" and "EditingDidEnd" to an IBAction


@IBAction func editingFinished(_ sender: UITextField) {
     let currentInput = sender.text!
     if currentInput.count > 5 || currentInput.count < 3 {   // Refuse more than 5 chars as 23:59 or less than 3 chars but accepts 123 as 1:23
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }

     var posOfColon = currentInput.index(of: ":")
     let withColon = posOfColon != nil
     var hh = ""
     var mm = ""

     if withColon {
          hh = String(currentInput[..<posofcolon!])
          let mmIndex = currentInput.index(posOfColon!, offsetBy: 1)
          mm = String(currentInput[mmIndex...])
     } else {
          mm = String(currentInput.suffix(2))     // Always 2 digits for minutes
          if currentInput.count == 4 {  // format as 1234
               hh = String(currentInput.prefix(2))     // first 2 digits
          } else {  // Only 3 chars
               hh = String(currentInput.prefix(1))     // Only one digit here
          }
     }
     if Int(hh) == nil || Int(hh)! > 23  {
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }
     if Int(mm) == nil || Int(mm)! > 59  {
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }
    
     // Use hh and mm as needed
}


For case b connect "Editing changed" to an IBAction


@IBAction func editingTestField(_ sender: UITextField) {

     }

Replies

The “platform standard” way would be to use a UIPickerView as the input view for the text field, rather than entering text. Personally I don’t like the way they feel though. It’s my least favourite Apple-designed UI widget. So I don’t really have a great answer. But that seems like the obvious choice.


if you really want to force the user to type, I would suggest using the numeric keypad, and use the UITextField delegate callbacks (text should/did change characters in range) to do any filtering or adding of extra characters like the colon.


There‘s probably a minefield of localization issues to think about too.

Would you mind to provide me an example?

I'm new using Swift...


Thanks

You have 2 ways :

a- wait till the user has completed the textField and hit return to test the content is correct

b- test after each key press that format is correct.


In anycase, the most effective would be to use a regular expression to test, but if yopu prefer to do it manually, can do this:


For case a, connect the UITextField sentMessages "DidEndOnExit" and "EditingDidEnd" to an IBAction


@IBAction func editingFinished(_ sender: UITextField) {
     let currentInput = sender.text!
     if currentInput.count > 5 || currentInput.count < 3 {   // Refuse more than 5 chars as 23:59 or less than 3 chars but accepts 123 as 1:23
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }

     var posOfColon = currentInput.index(of: ":")
     let withColon = posOfColon != nil
     var hh = ""
     var mm = ""

     if withColon {
          hh = String(currentInput[..<posofcolon!])
          let mmIndex = currentInput.index(posOfColon!, offsetBy: 1)
          mm = String(currentInput[mmIndex...])
     } else {
          mm = String(currentInput.suffix(2))     // Always 2 digits for minutes
          if currentInput.count == 4 {  // format as 1234
               hh = String(currentInput.prefix(2))     // first 2 digits
          } else {  // Only 3 chars
               hh = String(currentInput.prefix(1))     // Only one digit here
          }
     }
     if Int(hh) == nil || Int(hh)! > 23  {
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }
     if Int(mm) == nil || Int(mm)! > 59  {
          sender.text = ""    // Clear it
          // Could play a beep
          return
     }
    
     // Use hh and mm as needed
}


For case b connect "Editing changed" to an IBAction


@IBAction func editingTestField(_ sender: UITextField) {

     }