2020年12月17日 星期四

TextField判斷是否輸入Emoji

 最近剛好遇到一個需求就是禁止在TextField內輸入Emoji的需求,

當Google後發現方式滿多的,可是都不是那麼的完美(包含原生Emoji判斷),

說不完美是因為可能需求在於地址,可是iPhone的User可能習慣連動打字,

不完美的原因在於如果使用編碼判斷的方式會造成輸入時只能一個字一個字輸入...

這樣對於使用者體驗個人是覺得很差的...

所以最後使用了原生的方法 請參考:官方文件

裡面總共有以下四個判斷Emoji的方法

而我一開始使用isEmoji發現他連聲符都擋掉了...可是他所以的Emoji都可以判斷出來

最後使用isEmojiPresentation,聲符沒擋了,但是部分的Emoji是可以輸入的...

所以上方才會提說原生判斷也不是那麼完美。

以下提供我所寫的方法

func containsEmoji() -> Bool {

        for scalar in unicodeScalars {

            if !scalar.properties.isEmojiPresentation {

                continue

            }

            return true

        }

        return false

    }

而我們會在text的delegate去判斷

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

        

        if textField == txtAddressDetail {

            if string.containsEmoji() {

                return false

            }

        }

}

當判斷是Emoji直接return false就不會進入輸入欄位了

另外附上正則式的寫法如下:

func hasEmoji() -> Bool {

        let pattern = "[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\\u2026\\u2022\\u20ac\r\n]"

        let pred = NSPredicate(format: "SELF MATCHES %@",pattern)

        return pred.evaluate(with: self)

    }

基本上用法是一樣的,但是不完美的就是上方所提的輸入問題,只能一個字一個字輸入。

再來就是每年可能都會有新的Emoji,Unicode要每年都去更新...

以上跟大家方享我目前所用的方法跟想法,如果您有更好的方法可以完美的呈現歡迎交流唷^^