Last active
October 24, 2019 10:05
-
-
Save davidleee/48322904c70b4ce82facc2c77c1566d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
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 | |
}) | |
} | |
// The next tricks are mostly to demonstrate how tricky it can be to determine emoji's | |
// If anyone has suggestions how to 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? | |
for 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? | |
for 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 | |
} | |
} | |
extension UnicodeScalar { | |
var isEmoji: Bool { | |
switch value { | |
case 0x1F600...0x1F64F, // Emoticons | |
0x1F300...0x1F5FF, // Misc Symbols and Pictographs | |
0x1F680...0x1F6FF, // Transport and Map | |
0x1F1E6...0x1F1FF, // Regional country flags | |
0x2600...0x26FF, // Misc symbols | |
0x2700...0x27BF, // Dingbats | |
0xFE00...0xFE0F, // Variation Selectors | |
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs | |
127000...127600, // Various asian characters | |
// 65024...65039, // Variation selector, duplicate to 0xFE00...0xFE0F | |
9100...9300, // Misc items | |
8400...8447: // Combining Diacritical Marks for Symbols | |
return true | |
default: return false | |
} | |
} | |
var isZeroWidthJoiner: Bool { | |
return value == 8205 | |
} | |
} |
Author
davidleee
commented
Jul 30, 2018
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment