質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1292閲覧

UITextViewでのattributedTextにおいての、日本語の扱い方について

affluenceyou

総合スコア44

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/11/09 07:49

編集2018/11/09 08:59

iOSのUITextViewでattributedTextの扱い方について質問したいです。

私がしたいことはUItextViewのtextViewDidChangeが呼ばれたとき、現在textViewに記入されている文字を、テキスト量によってスタイルを変えたいということです。
もっと具体的にいうと、30文字を超えたら、超えている分の文字は赤色に変更したいです。

私がとった方法としては、通常の文字列と超過分の文字列を二つのattributedTextに分割してスタイリングをして、そのあとにそれらを繋げてtextView.attributedTextに代入するというものでした。
試したコードは以下の通りです。textViewのdidChange時に呼ばれるコードです。

swift

1let currentCount = textView.text.count 2if(currentCount > 30) { 3 let enabledStringAttributes: [NSAttributedString.Key : Any] = [ 4 .foregroundColor : UIColor.black, 5 .font : UIFont.systemFont(ofSize: 15.0) 6 ] 7 let enabledText = NSMutableAttributedString(string: String(textView.text.prefix(30)), attributes: enabledStringAttributes) 8 9 let disenabledStringAttributes: [NSAttributedString.Key : Any] = [ 10 .foregroundColor : UIColor.red, 11 .font : UIFont.systemFont(ofSize: 15.0) 12 ] 13 14 let from = textView.text.index(textView.text.startIndex, offsetBy: 30) 15 let disenabledText = NSMutableAttributedString(string: String(textView.text[from...]), attributes: disenabledStringAttributes) 16 17 let mutableAttributedString = NSMutableAttributedString() 18 mutableAttributedString.append(enabledText) 19 mutableAttributedString.append(disenabledText) 20 21 textView.attributedText = mutableAttributedString 22

しかしこれだと、なぜか30文字を超えた入力からおかしな挙動になります。以下のスクリーンショットは、30文字目入力時点、31文字目に「お」を入力した時点、32文字目に「い」を入力したものになります。
イメージ説明
イメージ説明
イメージ説明
そもそもの方向性が違うのか、少し変えればできるのか、しばらく格闘してみましたがわかりませんでした。
どなたかご教示して頂けると幸いです。
よろしくお願いします。

追記1
英語だとうまくいっていることがわかりました。これは日本語の扱いによる問題なのでしょうか? だとするとどうすれば解決できるのか... ご教示して頂けると嬉しいです。

追記2
やはり日本語変換の問題だと判明しました。

swift

1if(textView.markedTextRange == nil) { 2 myTextViewDelegate?.textViewDidChange(textView: textView) 3}

で上のコードを呼び出すことで、「入力確定時」に期待した色になることを確認できました。しかし変換中は30文字を超えていてもずっと黒いままであり、変換終了後に一気に赤くなるような仕様になってしまいます。これを解決する方法はあるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

razuma

2018/11/09 09:55

textView.typingAttributesで未確定時でもattributeを変えることができましたが、全ての文字が赤くなってしまうため、markedText内でattributeを分けて表示させるようなことは難しいのかなと思いました。解決方法が見つからなかったのですがご参考までにコメントさせていただきました。
affluenceyou

2018/11/09 10:16

割と難易度高めなのですかね... そういえばTwitterでさえ変換確定時に文字数の制御をしてるっぽいので、なかなか困難そうなことがわかりました。コメントありがとうございました!
guest

回答1

0

ベストアンサー

私もチャレンジしてみましたが、変換中の文字っておそらく編集できないですよね。あるいはUITextViewのattributedTextがMutableだったり、attributedのRangeを無限指定できればと思いましたがやはりだめなようで。

ちなみにカウントだけなら可能です。textView:shouldChangeTextInRange:replacementTextを使います。
なので、例えば未確定時のテキストの文字数をカウントして30文字を超えたらエラーをどこかに出すとかならできます。

投稿2018/11/10 10:20

kosanai

総合スコア471

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

razuma

2018/11/10 10:36 編集

ちょっと考えたのはUITextViewもどきの自作?フォーカス自体は裏でUITextViewに持たせて文字の反映をUITextViewもどきの方にさせてmarkedTextのようなふるまいを自作したらできるかなと思いました。(本来の意味合いとは違いますが、目的を達成するために強引にやるとしたら。試してないのでうまくいくかはわかりませんが)変換中を扱う必要がある言語と言うのもなかなか特殊だと思うので仮になんらかの方法でできたとしても情報を探すのが難しいかもしれませんね。(なんとなく無理そうではありますが)
kosanai

2018/11/10 10:46

カスタマイズしようにも、やはり変換中の文字の問題が出るのではないでしょうか ・30文字を超えた時に、未確定状態で31文字目から色を変える これが難しいです あとは ・30文字入力後、31文字目の未確定文字を赤くする も難しいですね それ以外はできましたが 31文字目を確定しないとそれ以降色が変えられません
razuma

2018/11/10 11:20 編集

UITextViewもどきと言いつつ、特にUITextViewなどを継承するわけではなく、UIViewの上にUILabelを乗せてUITextViewのように見せる仕組みを考えていました。未確定のときも未確定のような半透明の青いものを乗せる、カーソルのようなものを作って最後尾に表示させる・・・のような感じです。(本当にやるの?と言われたら私はやりませんが・・・)
affluenceyou

2018/11/11 04:52

回答ありがとうございます! 機能的には30文字を超えた時点で送信ボタンを押せなくすることはできるので、カウントに関しては問題ないのですが、未確定の文字色を変更したかったです。議論を拝見したところやはり難易度が高い(あるいは無理?)なようなので、一旦は妥協して確定時に文字色を変更したいと思います。 お二方ありがとうございました!
kosanai

2018/11/13 05:26

ちなみにこう言う要求は誰もが一回考えると思うので、誰かライブラリ化してる可能性はありますよね。(もし見つけたらネットのどこかに書いてほしいです????)と言っても私も何度か探してダメだったのですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問