背景
超久しぶりに文字列と戦ったのでここで残しておきたい!
みんなも文字のカウントいつ何を使えばいいか思い出してみましょう
例のこちら文字列値がある
@Binding var text: String
でその文字列に超えた制限だけハイライトをしたいな〜と思ったあなたへ、文字のみであればtext.countでも全然十分!
ただ、multibyte絵文字含めてしまうとどう計算すればいいのでしょうか?
text.count
上記の書いた通りに文字しか想定していない場合はこれだけでいける!
let text = "Hi my name is Adam!"
print(text.count) // 24
let textView = UITextView()
textView.frame = CGRect(x: 150, y: 200, width: 200, height: 50)
let attributedText = NSMutableAttributedString(string: text)
attributedText.addAttributes(
[.font: UIFont.systemFont(ofSize: 18),
.foregroundColor: UIColor.gray],
range: .init(location: 0, length: text.count)
)
if text.count > 5 {
attributedText.addAttributes(
[.backgroundColor: UIColor.red],
range: .init(location: 0, length: text.count)
)
}
でも次は絵文字使ってみましょう
let text = "Hi 🗿 my name is Adam😉😉😉!"
text.count
だと24が出ますが、NSAttributedString
のRange
だと計算ロジックと違う
それで絵文字の途中までattribute
をかけているから文字化けしている
text.utf16.count
UTF-16を使ってみましょう
let text = "Hi 🗿 my name is Adam😉😉😉!"
print(text.count) // 24
print(text.utf16.count) // 28
let textView = UITextView()
textView.frame = CGRect(x: 150, y: 200, width: 200, height: 50)
let attributedText = NSMutableAttributedString(string: text)
attributedText.addAttributes(
[.font: UIFont.systemFont(ofSize: 18),
.foregroundColor: UIColor.gray],
range: .init(location: 0, length: text.utf16.count)
)
if text.utf16.count > 5 {
attributedText.addAttributes(
[.backgroundColor: UIColor.red],
range: .init(location: 0, length: text.utf16.count)
)
}
textView.attributedText = attributedText
Summary
しばらく使っていないと忘れやすい!ので誰か役に立ったら嬉しい!
もし絵文字+NSAttributedStringを一緒に使うんだったらUTF-16を使いましょう!!