[英]How do you turn a string into a unicode family in Swift?
I'm trying to make a feature in my app that when a user types in a text field, the text converts into a unicode family. 我正在尝试在我的应用程序中创建一个功能,当用户在文本字段中键入内容时,文本将转换为unicode系列。
Like below, there is an image of a user typing. 像下面一样,有一个用户输入的图像。 And as the user types, you can see different unicode family characters that when a user types on a cell, you can copy the text and paste it somewhere else. 在用户键入内容时,您会看到不同的unicode系列字符,当用户在单元格上键入内容时,您可以复制文本并将其粘贴到其他位置。
If I would like to turn my text into the black bubble unicode family like the screenshot above, how can I do that? 如果我想像上面的屏幕截图一样将文本变成黑色气泡unicode系列,该怎么办?
You can define a character map. 您可以定义一个字符映射。 Here's one to get you started. 这是一个入门的方法。
let circledMap: [Character : Character] = ["A": "🅐", "B": "🅑", "C": "🅒", "D": "🅓"] // The rest are left as an exercise
let circledRes = String("abacab".uppercased().map { circledMap[$0] ?? $0 })
print(circledRes)
If your map contains mappings for both upper and lowercase letters then don't call uppercased
. 如果您的地图同时包含大写和小写字母的映射,则不要调用uppercased
。
Create whatever maps you want. 创建所需的任何地图。 Spend lots of time with the "Emoji & Symbols" viewer found on the Edit menu of every macOS program. 使用每个macOS程序的“编辑”菜单上的“表情符号和符号”查看器,花费大量时间。
let invertedMap: [Character : Character] = ["a": "ɐ", "b": "q", "c": "ɔ", "d": "p", "e": "ǝ", "f": "ɟ", "g": "ƃ", "h": "ɥ"]
In a case like the circled letters, it would be nice to define a range where you can transform "A"..."Z"
to "🅐"..."🅩"
. 在带圆圈的字母的情况下,最好定义一个范围,在该范围内可以将"A"..."Z"
为"🅐"..."🅩"
。
That actually takes more code than I expected but the following does work: 实际上,这比我预期的要花费更多的代码,但是以下方法确实有效:
extension String {
// A few sample ranges to get started
// NOTE: Make sure each mapping pair has the same number of characters or bad things may happen
static let circledLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "🅐"..."🅩", "a"..."z" : "🅐"..."🅩"]
static let boxedLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "🅰"..."🆉", "a"..."z" : "🅰"..."🆉"]
static let italicLetters: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>] = ["A"..."Z" : "𝐴"..."𝑍", "a"..."z" : "𝑎"..."𝑧"]
func transformed(using mapping: [ClosedRange<UnicodeScalar> : ClosedRange<UnicodeScalar>]) -> String {
let chars: [UnicodeScalar] = self.unicodeScalars.map { ch in
for transform in mapping {
// If the character is found in the range, convert it
if let offset = transform.key.firstIndex(of: ch) {
// Convert the offset from key range into an Int
let dist = transform.key.distance(from: transform.key.startIndex, to: offset)
// Build new index into value range
let newIndex = transform.value.index(transform.value.startIndex, offsetBy: dist)
// Get the mapped character
let newch = transform.value[newIndex]
return newch
}
}
// Not found in any of the mappings so return the original as-is
return ch
}
// Convert the final [UnicodeScalar] into a new String
var res = ""
res.unicodeScalars.append(contentsOf: chars)
return res
}
}
print("This works".transformed(using: String.circledLetters)) // 🅣🅗🅘🅢 🅦🅞🅡🅚🅢
The above String
extension also requires the following extension (thanks to this answer ): 上面的String
扩展也需要以下扩展(由于此答案 ):
extension UnicodeScalar: Strideable {
public func distance(to other: UnicodeScalar) -> Int {
return Int(other.value) - Int(self.value)
}
public func advanced(by n: Int) -> UnicodeScalar {
let advancedValue = n + Int(self.value)
guard let advancedScalar = UnicodeScalar(advancedValue) else {
fatalError("\(String(advancedValue, radix: 16)) does not represent a valid unicode scalar value.")
}
return advancedScalar
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.