テキストを選択できるようにしたら、リンクが開けるようにしたり、スクロールできるようにしたりするため、UILabelをわかりにUITextViewを使いがちですが、いったいUILabelと完全に同じようになれるでしょうか?

操作を無効

textView.isEditable = false
// 必要に応じて
textView.isSelectable = false
textView.isScrollEnabled = false

周囲のスペースを除去

textView.textContainerInset = .zero
textView.textContainer.lineFragmentPadding = 0

attributedText

基本的に上記の対応は十分ですが、textではなく、attributedTextを使う場合いろいろな問題が出ます。

フォント

UILabelの場合、前もってfontを設定していれば、後で設定するattributedTextにも反映できます。しかしUITextViewでは前もってfontを設定することができません。

とはいえattributedTextを設定した度に、fontを設定すること、またはNSAttributedStringにフォントを指定することで問題が解決できます。

ここにワナがあります。attributedTextを設定した度に、fontがデフォルトに戻されるように見え、デフォルトフォントで良いの場合はfontを設定しなくてもいいと思いますよね。そうでもありません。

`text`|`attributedText`
textattributedText

サイズが14ptから12ptになっただけではなく、フォントもなぜかHelveticaになりました。

下線

フォントをちゃんと設定すればこれ以上の問題がないと思いきや、下線の位置が違います。

`UILabel`|`UITextView`
UILabelUITextView

フォントは完全に一緒ですが、下線だけ違うということは、簡単に対応できる方法がないはずです。

ヒラギノ

フォントをヒラギノに設定することはおすすめしないのですが、もし設定したらどうなるかを見てみましょう。

`UILabel`|`UITextView`
UILabelUITextView

下線の位置の違いがもって大きいし、下に大きなスペースがあります。

測ってみたら、UIFont.leadingが使われているように見えます。システムフォントの場合、このスペースがないのはシステムフォントのleadingが0だからかもしれません。

ちなみにフォントを設定しないでattributedTextを設定し、Helveticaになる場合はシステムフォントのような特別な調整がなくて、直接にHiragino Sansに変更されて、画像のように文字と下線の距離は結構あるため、下線が外部に出て、表示できなくなります。

可能な原因

UILabelは静的な部品ですが、UITextViewは入力のために作られた部品で、入力しながら行の高さや下線の位置がわからない(Xcodeができていない😅)ようにするため、UILabelよりいろんな工夫をしているはずで、それが原因だと私が思います。

まとめ

UITextViewUILabelとして使うことは可能ですが、細かいところ(特にattributedTextを設定する場合)に違いが出ます。とはいえ大きな違いではないので、気にしなくても良いかと思います。

気にする場合はUILabelを使って、必要な機能を別の方向で実装しましょう。

  • 選択可能:無理?
  • リンクが開ける:UITapGestureRecognizer
  • スクロール可能:UIScrollView