Как изменить размер UITextView во время ввода внутри него?
Я создаю раздел комментариев, похожий на тот, который использует Facebook для обмена сообщениями в приложении iOS. Я хочу, чтобы UITextView
изменял размер высоты, чтобы текст, который я вводил, вписывался в него, а не вам приходилось прокручивать текст, который переполняется. Любые идеи о том, как я могу это сделать? Я рассмотрел, возможно, используя CGRect
, который назначен размеру и высоте текстового представления, которое затем соответствует размеру содержимого:
CGRect textFrame = textView.frame;
textFrame.size.height = textView.contentSize.height;
textView.frame = textFrame;
Я предполагаю, что мне нужна какая-то функция, которая обнаруживает, когда текст достигает границ UITextView
, а затем изменяет размер высоты представления? Кто-нибудь боролся с этой же концепцией?
Ответы
Ответ 1
Вы можете настроить фрейм в этом методе делегата, не забудьте установить делегат textView для себя.
-(BOOL)textView:(UITextView *)_textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
[self adjustFrames];
return YES;
}
-(void) adjustFrames
{
CGRect textFrame = textView.frame;
textFrame.size.height = textView.contentSize.height;
textView.frame = textFrame;
}
это решение для iOS6 и ранее... для iOS7 см. этот
fooobar.com/questions/9702/...
Ответ 2
Это мое решение, используя autolayout и textView.contentSize.height
. Протестировано на iOS8 Xcode6.3 beta4.
В конце один раз обманите setContentOffset
. Я поставил его, чтобы избежать артефакта "неправильного содержимого", когда число строк изменяется. Он добавляет лишнее лишнее пустое место под последней строкой, и это выглядит не очень хорошо, если вы не установите его сразу после изменения ограничения. Взял мне время, чтобы понять это!
// set this up somewhere
let minTextViewHeight: CGFloat = 32
let maxTextViewHeight: CGFloat = 64
func textViewDidChange(textView: UITextView) {
var height = ceil(textView.contentSize.height) // ceil to avoid decimal
if (height < minTextViewHeight + 5) { // min cap, + 5 to avoid tiny height difference at min height
height = minTextViewHeight
}
if (height > maxTextViewHeight) { // max cap
height = maxTextViewHeight
}
if height != textViewHeight.constant { // set when height changed
textViewHeight.constant = height // change the value of NSLayoutConstraint
textView.setContentOffset(CGPointZero, animated: false) // scroll to top to avoid "wrong contentOffset" artefact when line count changes
}
}
Ответ 3
На TableViewController, который содержит UITextView, обновите данные из tableViewDataSource, который помещается в ячейку, а затем просто вызовите это:
tableView.beginUpdates()
tableView.endUpdates()
В отличие от tableView.reloadData(), это не вызывает resignFirstResponder
Ответ 4
Сначала установите минимальные ограничения высоты для вашего TextView:
textView.heightAnchor.constraint(greaterThanOrEqualTo: view.heightAnchor, multiplier: 0.20)
(Убедитесь, что вы устанавливаете ограничение LargeThanOrEqualTo Constraint, чтобы, если высота внутреннего содержимого больше этой высоты, она занимает внутреннюю высоту содержимого)
ИЛИ простая константа
textView.heightAnchor.constraint(greaterThanOrEqualToConstant: someConstant)
При настройке вашего textView установите isScrollEnabled в значение false
textView.isScrollEnabled = false
Теперь, когда вы вводите текст textView, высота его собственного размера будет увеличиваться, и он автоматически откроет представления под ним.
Ответ 5
contentsize
не будет работать в ios 7.
Попробуйте следующее:
CGFloat textViewContentHeight = textView.contentSize.height;
textViewContentHeight = ceilf([textView sizeThatFits:textView.frame.size].height + 9);