UITextViewでテキスト初期表示位置が中央付近にズレて上部が見切れた状態で表示される問題への対応
ということについて備忘録がてら書いておこうかと思います。ただし、結局のところ、その時点ではうまくいったように見えるけれども、振り返ってみると使われていなくてもうまくいってるといったような具合で、要するに原因と解決策がわからずにいます。
問題
というように、TextViewの文章を書き出しからの表示になっておらず、アプリとしてかなり不恰好です。何が問題で、どのように解決が図れるのでしょうか。
対応
ここに記載されているのも、はじめはそれでうまく行ったけれど、後であらためて試してみるとどうもうまくいかなかったりと、とりあえず同じような問題が生じたらまず試してみて解決を図るくらいのものです。
位置を指定
textView.setContentOffset(CGPoint.zero, animated: false)
//位置の指定は様々ですが、初期位置で合わせるなら`.zero`で可能
.zero
、左上に合わせる。
記事によってはsetContentOffset
での調整は沼にハマるということも書かれており、フレームで指定するように記述されていました。ただ、現在でも当てはまるのかは不明で、使ってみる限りとくに問題ないように思えました。
自動調整をオフ
他の記事でもこうしたらうまくいくというのが、このInsetsの自動調整の設定でした。
いくつか日本語で書かれたQiitaの記事が見受けられましたが、StackOverFlowがとりあえずのところは網羅的に書かれているように見受けられました。
ただ、そもそもの問題がうまく得られないので検証ができない...
1.Stroyboardのinspectorで設定
デフォルトではAutomatic
ですが、Never
とすることでInsetの自動調整がオフになります。自動調整されないので、基本的にはAutoLayout通りの表示となるはずです。
2.コードで設定
//deprecated
textView.automaticallyAdjustsScrollViewInsets = false
スクロールビューのインセットの自動調整をしない設定にする、と書かれていた記事がありました。テキストビューはスクロールビューのサブクラスであるため、スクロールビューのメソッドが反映されます。ただし、調べてみると、現在はdeprecatedのようです。
iOS11からは新たにcontentInsetAdjustmentBehavior
に変わっているようです。iOS11からなので、もう特に気にせずにこちらだけ記述すればよさそう。
textView.contentInsetAdjustmentBehavior = .never
原因
他のプロジェクトでうまく再現できなかったため、これは推測でしかありませんが、NavigationControllerとTabBarControllerからの遷移を同一のViewControllerに指定していると、Insetsが自動調整された結果、NavigationBarがTextViewに覆いかぶさってしまっているのではないかと考えました。
ただ、具体的に再現できなかったのと、問題の生じたViewControllerからあれこれSegueを付けたり外したりしても、ちっとも直らなかったりするので、正直なところよくわかりません。
Insetsに関してはAppleのドキュメントを分かりやすくまとめてくださっている記事があるので、より詳しい理解はこちらをぜひ読んでみてください。
一応原因をこのように考えると、表示位置をoffsetによってズラすよりも、本質的な問題はこの自動調整の設定にあるので、その解決を図ろうと考えたらやはりこの設定を見直すというのが望ましそうな気がします。
参考
Discussion