0

I created a union between two character sets to be able to use a period with the decimalDigits character set.

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

            let allowed = CharacterSet.decimalDigits
            let period = CharacterSet.init(charactersIn: ".")
            let both = CFCharacterSetUnion(allowed as! CFMutableCharacterSet, period as CFCharacterSet)

            let characterSet = NSCharacterSet(charactersIn: string)

            return both.isSuperset(of: characterSet as CharacterSet)
        }

however, returning "both.isSuperset(of: characterSet as CharacterSet)". how to correct?

Update 1: Errors displayed with the current suggested answer enter image description here

Update 2: latest update enter image description here

Jon Gi
  • 39
  • 1
  • 8

1 Answers1

3

Try doing this instead:

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

    var allowed = CharacterSet.decimalDigits
    let period = CharacterSet.init(charactersIn: ".")
    allowed.formUnion(period)

    //UNCOMMENT when isSuperset is working
    //let characterSet = CharacterSet(charactersIn: string)
    //return allowed.isSuperset(of: characterSet)

    // Swift 3 appropriate solution 
    let isSuperset = string.rangeOfCharacter(from: allowed.inverted) == nil
    return isSuperset
}

the basis for which I found here.

Even better, make "allowed" (or "both", whatever you decide to name it) a property that gets created in viewDidLoad so you don't recreate and union the character sets each time a character is typed.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • Would you be able to continue with the answer? I apologize, haha, I'm receiving an error with your above answer. Ill post in a second – Jon Gi Jun 24 '17 at 00:09
  • Turns out you ran into a bug! [`isSuperset` doesn't work properly in Swift 3](https://forums.developer.apple.com/thread/63262) – Michael Dautermann Jun 24 '17 at 00:34
  • regardless, thank you so much for a workable solution! ive been racking my brain over this for hours. – Jon Gi Jun 24 '17 at 00:58
  • Michael, wanted to ask for further clarification. Why is it that when we set the isSuperset variable, we add the "== nil"? Why can't we simply say "= true" considering the func returns a bool? – Jon Gi Jun 25 '17 at 15:52
  • 1
    Basically what that line is saying is: "return the range of any characters in the string that match characters ***NOT*** found in the allowed set". So if a range is not found, `string` is covered by that superset (no range returned equals nil which makes `isSuperset` true). If a range is found, there's an invalid / not-allowed character in it (i.e. `isSuperset` is set to false and the `string` won't be changed) Hopefully this makes sense? – Michael Dautermann Jun 25 '17 at 17:40