ios - Find out if Character in String is emoji? -


i need find out whether character in string emoji.

for example, have character:

let string = "๐Ÿ˜€" let character = array(string)[0] 

i need find out if character emoji.

what stumbled upon difference between characters, unicode scalars , glyphs.

for example, glyph ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง consists of 7 unicode scalars:

  • four emoji characters: ๐Ÿ‘จ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘ง
  • in between each emoji special character, works character glue; see the specs more info

another example, glyph ๐Ÿ‘Œ๐Ÿฟ consists of 2 unicode scalars:

  • the regular emoji: ๐Ÿ‘Œ
  • a skin tone modifier: ๐Ÿฟ

so when rendering characters, resulting glyphs matter.

what looking way detect if string , 1 emoji. render larger normal text (like messages on ios10 , whatsapp nowadays). described above, character count of no use. (the 'glue character' not considered emoji).

what can use coretext break down string glyphs , count them. furthermore, move part of extension proposed arnold , sebastian lopez separate extension of unicodescalar.

it leaves following result:

import uikit  extension unicodescalar {      var isemoji: bool {          switch value {         case 0x1f600...0x1f64f, // emoticons             0x1f300...0x1f5ff, // misc symbols , pictographs             0x1f680...0x1f6ff, // transport , map             0x2600...0x26ff,   // misc symbols             0x2700...0x27bf,   // dingbats             0xfe00...0xfe0f,   // variation selectors             0x1f900...0x1f9ff,  // supplemental symbols , pictographs             65024...65039, // variation selector             8400...8447: // combining diacritical marks symbols             return true          default: return false         }     }      var iszerowidthjoiner: bool {          return value == 8205     } }  extension string {      var glyphcount: int {          let richtext = nsattributedstring(string: self)         let line = ctlinecreatewithattributedstring(richtext)         return ctlinegetglyphcount(line)     }      var issingleemoji: bool {          return glyphcount == 1 && containsemoji     }      var containsemoji: bool {          return unicodescalars.contains { $0.isemoji }     }      var containsonlyemoji: bool {          return !isempty             && !unicodescalars.contains(where: {                 !$0.isemoji                     && !$0.iszerowidthjoiner             })     }      // next tricks demonstrate how tricky can determine emoji's     // if has suggestions how improve this, please let me know     var emojistring: string {          return emojiscalars.map { string($0) }.reduce("", +)     }      var emojis: [string] {          var scalars: [[unicodescalar]] = []         var currentscalarset: [unicodescalar] = []         var previousscalar: unicodescalar?          scalar in emojiscalars {              if let prev = previousscalar, !prev.iszerowidthjoiner && !scalar.iszerowidthjoiner {                  scalars.append(currentscalarset)                 currentscalarset = []             }             currentscalarset.append(scalar)              previousscalar = scalar         }          scalars.append(currentscalarset)          return scalars.map { $0.map{ string($0) } .reduce("", +) }     }      fileprivate var emojiscalars: [unicodescalar] {          var chars: [unicodescalar] = []         var previous: unicodescalar?         cur in unicodescalars {              if let previous = previous, previous.iszerowidthjoiner && cur.isemoji {                 chars.append(previous)                 chars.append(cur)              } else if cur.isemoji {                 chars.append(cur)             }              previous = cur         }          return chars     } } 

which give following results:

"๐Ÿ‘Œ๐Ÿฟ".issingleemoji // true "๐Ÿ™Ž๐Ÿผโ€โ™‚๏ธ".issingleemoji // true "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".issingleemoji // true "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".containsonlyemoji // true "hello ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".containsonlyemoji // false "hello ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".containsemoji // true "๐Ÿ‘ซ hรฉllo ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".emojistring // "๐Ÿ‘ซ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง" "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".glyphcount // 1 "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".characters.count // 4  "๐Ÿ‘ซ hรฉllล“ ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".emojiscalars // [128107, 128104, 8205, 128105, 8205, 128103, 8205, 128103] "๐Ÿ‘ซ hรฉllล“ ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง".emojis // ["๐Ÿ‘ซ", "๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง"]  "๐Ÿ‘ซ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ".issingleemoji // false "๐Ÿ‘ซ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ".containsonlyemoji // true "๐Ÿ‘ซ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ".glyphcount // 3 "๐Ÿ‘ซ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ".characters.count // 8 

Comments

Popular posts from this blog

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -

oracle - Changing start date for system jobs related to automatic statistics collections in 11g -