I have a textField and the checking is done in shouldChangeCharactersIn function. This is working well in most cases.
First I have a CharacterSet of allowed characters:
// Check characters
allowedCharacters = CharacterSet.decimalDigits.union(.letters)
allowedCharacters = allowedCharacters?.union(CharacterSet(charactersIn: "àÀáÁâÂãÃäÄåāÅæèÈéÉêÊëËìÌíÍîÎïÏòÒóÓöÖôÔõÕøØùÙúÚûÛüÜýÝÿçÇñÑ"))
allowedCharacters = allowedCharacters?.union(CharacterSet(charactersIn: " ,.:;@#%* &_=<>!?\r\n'(){}[]/-"))
The allowedCharacters variable now holds all the characters that I wish to allow in my app. The trimminCharacters removes all characters not in the allowed set.
guard string.trimmingCharacters(in: allowedCharacters!) == "" else { return false }
This seems to be working okay, but when the user switches Keyboard to Turkish or Chinese, it is possible to enter characters that are not in the list above. Eg. from the Turkish keyboard: ğ and ş And from Chinese keyboard: ㄎ ㄕ and ㄨ
I want to block all characters not in the allowed CharacterSet. How can I prevent the user from inputting these characters?
CodePudding user response:
The letters
character set includes every unicode scalar whose category starts with "L" or "M".
Well, ğ and ş are both in the category Ll (Lowercase Letter), and the Bopomofo symbols ㄎ ㄕ and ㄨ are all in the category Lo (Other Letter). All these characters are in the letter
character set!
Note that the same thing goes for decimalDigits
, which includes everything in the category Nd. This includes the Indic Arabic numbers ٠١٢٣٤٥٦٧٨٩ for example.
You seem to have a rather specific set of characters that you want to allow, so you should just write that out explicitly:
CharacterSet(charactersIn: "a"..."z") // assuming these chars are what you want
.union(.init(charactersIn: "A"..."Z"))
.union(.init(charactersIn: "0"..."9"))
.union(.init(charactersIn: "àÀáÁâÂãÃäÄåāÅæèÈéÉêÊëËìÌíÍîÎïÏòÒóÓöÖôÔõÕøØùÙúÚûÛüÜýÝÿçÇñÑ"))
.union(.init(charactersIn: " ,.:;@#%* &_=<>!?\r\n'(){}[]/-"))