チャットの入力欄のように、文字列の長さによって入力欄の高さが動的に変わる UITextView
の実装となりますが、一般的には、
https://hacknote.jp/archives/7958/ のように textViewDidChange
で sizeThatFits
を呼び出して高さを設定する方法が多いと思います。
ただし、この方法の場合、カーソルや描画がちらついてしまうことがあります。
なお、GlowingTextView でも同様の現象が起こりまして、このライブラリを利用している slack などでも発生するようです。
https://github.com/HansPinckaers/GrowingTextView
サイズを計算する sizeThatFits
というメソッドですが、計算時にどうやら描画にも影響を与えているようです。
この現象を改善した、手法として、以下のようにダミーの UITextView
で sizeThatFits
でサイズを計算し、
文字入力が画面に反映される前に、高さを変更してしまう方法があります。
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { var dummyText: NSMutableString = NSMutableString(string: textView.text) dummyText.deleteCharactersInRange(range) dummyText.insertString(text, atIndex: range.location) let maxHeight:CGFloat = 100.0 let minHeight:CGFloat = 33.0 dummyTextView.frame = CGRectMake(0, 0, textView.frame.width, textView.frame.height) dummyTextView.font = textView.font dummyTextView.text = dummyText as String var size = dummyTextView.sizeThatFits(textView.frame.size) var height = size.height if(height < minHeight) { height = minHeight } if(height > maxHeight) { height = maxHeight } if (textFieldHeight.constant != height) { var offsetY = (textFieldHeight.constant - height) if((offsetY > 0 && height > maxHeight - offsetY) || (offsetY < 0 && height > maxHeight)) { offsetY = 0 } tableView.contentOffset.y = tableView.contentOffset.y - offsetY textFieldHeight.constant = height } return true }