Swift4.0において、UITextViewに後からテキストを代入した場合、スクロールは最後の状態になってしまいました。
スクリプトに保持していた文章データをUITextViewに代入して表示するだけのシンプルな処理をしたかったのですが、かなり解決に時間をかけてしまったので備忘録。
UITextViewが初期状態で一番上にならない状態
@IBOutlet weak var textView: UITextView!
let textData = "表示するテキスト...(実際はスクロールが必要になる程の長さ)"
override func viewWillAppear(_ animated: Bool){
textView.text = textData
}
このように単純に処理を書くと、textViewは一番下までスクロールされ、textDataの最後の部分を表示してしまいます。
ちょっと調べて改善してみた
ちょっと調べてみた結果、以下のようにすれば良いとのことでした。
@IBOutlet weak var textView: UITextView!
let textData = "表示するテキスト...(実際はスクロールが必要になる程の長さ)"
override func viewWillAppear(_ animated: Bool){
textView.text = textData
textView.setContentOffset( // 追加
CGPoint(x: 0, y: -textView.contentInset.top),
animated: false)
}
しかし、上の方までスクロールした状態にはなったものの、なんか微妙な位置で止まってしまいました。
CGPointのyの値を0にしたりマイナスにしてみたりしたのですが、結果は変わらず。。。
めっちゃ調べて解決してみた
妥協する手もあったのですが、スクロールが微妙な位置で表示されるのはあまりにダサいな。。。と思いまして、めっちゃ調べてみました。
そして、解決策が見つかりました!
解決策1
override func viewWillAppear(_ animated: Bool){
textView.text = textData
self.view.layoutIfNeeded() // 追加
textView.setContentOffset(
CGPoint(x: 0, y: -textView.contentInset.top),
animated: false)
}
解決策2
override func viewDidLayoutSubviews() { // 追加
textView.setContentOffset(
CGPoint(x: 0, y: -textView.contentInset.top),
animated: false)
}
override func viewWillAppear(_ animated: Bool){
textView.text = textData
// 削除
}
テキストを代入してから
self.view.layoutIfNeeded()
を呼んでレイアウトし直すか、
もしくは
override func viewWillAppear(_ animated: Bool){ }
の中でUITextViewのオフセットを設定するか
このどちらかで無事解決しました!!
特に理由がなければ解決策1の方が簡単で良いのではないかと思います。
コメント