UITextView って UITextField みたいに Placeholder がないんですね。つい先日まで気づきませんでした。必要とするようなシチュエーションがないとかそのような UI が iOS 的にナシなのかなぁと思っていたらカレンダーアプリのイベント追加画面で Apple 自身が実装してました。しょうがないので作りました。良かったら使ってみてください。CSTextView から CSNPlaceholderTextView に名称を変更しています。
CSNPlaceholderTextView
特徴
- 挙動は Calendar.app の イベント追加画面 (
EKEventEditViewController
)のメモの部分に似せている - placeholder の表示位置は Caret の位置に自動調整
- placeholder の font は textView 側の
font
プロパティに連動 - UITextView のリプレイスとして使えるように UITextViewDelegate を汚染しない
ということで、Placeholder として使っている Label の textColor は UITextField の placeholder プロパティの説明にあるように
The placeholder string is drawn using a 70% grey color.
な色にしてあったり、UITextViewDelegate を汚染しないように UITextiView が準拠している UITextInput プロトコルのメソッドをオーバーライドするようにして表示位置や出し入れを調整しています。
ハマったのはplaceholder の表示の On/Off を
- (CGRect)caretRectForPosition:(UITextPosition *)position
だけでやっていましたが、入力済みのテキストを Cut してから Undo Cut して Undo Typing したあとに placeholder が消えないことでした。
- (UITextRange *)selectedTextRange
メソッドはこの問題の動作でも呼ばれることがわかったのでここでも On/Off を行うことで回避しました。ただ、この方法が UITextInput とかのテキスト入力系 の振る舞いとして適切かどうかはちょっとわかりません。
追記
「text プロパティでテキストを代入すると placeholder が消えない」というバグがあったので修正しておきました。
CocoaPods 対応
pod 'CSNPlaceholderTextView', '~> 0.0'