0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NSAttributedStringと絵文字でなんで文字化けになる?

Posted at

背景

超久しぶりに文字列と戦ったのでここで残しておきたい!
みんなも文字のカウントいつ何を使えばいいか思い出してみましょう

例のこちら文字列値がある

@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)
            )
        }

こんな結果が出ます
Screen Shot 2022-12-27 at 15.40.07.png

でも次は絵文字使ってみましょう

let text = "Hi 🗿 my name is Adam😉😉😉!"

Screen Shot 2022-12-27 at 15.41.47.png

text.countだと24が出ますが、NSAttributedStringRangeだと計算ロジックと違う
それで絵文字の途中まで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

これでは思い通りの結果になる!やった〜
Screen Shot 2022-12-27 at 15.49.17.png

Summary

しばらく使っていないと忘れやすい!ので誰か役に立ったら嬉しい!
もし絵文字+NSAttributedStringを一緒に使うんだったらUTF-16を使いましょう!!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?