как сделать динамическую высоту UITextView в соответствии с длиной текста?
Как вы можете видеть на этом изображении
UITextView
изменяет высоту в соответствии с длиной текста, я хочу настроить ее высоту в соответствии с длиной текста.
* Я видел другие вопросы, но решения там не работали для меня
Ответы
Ответ 1
это работает для меня, других решений нет.
func adjustUITextViewHeight(arg : UITextView)
{
arg.translatesAutoresizingMaskIntoConstraints = true
arg.sizeToFit()
arg.scrollEnabled = false
}
В Swift 4 синтаксис arg.scrollEnabled = false
изменился на arg.isScrollEnabled = false
.
Ответ 2
Попробуйте:
CGRect frame = self.textView.frame;
frame.size.height = self.textView.contentSize.height;
self.textView.frame = frame;
Edit- Здесь Swift:
var frame = self.textView.frame
frame.size.height = self.textView.contentSize.height
self.textView.frame = frame
Ответ 3
В Storyboard/Interface Builder просто отключите прокрутку в инспекторе атрибутов.
В коде textField.isScrollEnabled = false
должен делать трюк.
Ответ 4
Swift 4
Добавить в свой класс
UITextViewDelegate
func textViewDidChange(_ textView: UITextView) {
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame
}
Ответ 5
Затем отвечает Дея Элдин.
В моем случае. Я автоматически увеличиваю высоту текста, добавляя
быстрый 3
textView.translatesAutoresizingMaskIntoConstraints = false textView.isScrollEnabled = false
Ответ 6
просто подключитесь к своей структуре.
@IBOutlet var textView: UITextView!
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!
и используйте этот код ниже
textViewHeightConstraint.constant = self.textView.contentSize.height
Ответ 7
это прямое намерение сделать программным образом. просто выполните следующие действия
-
добавить наблюдателя в длину содержимого текстового поля
[yourTextViewObject addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
-
осуществлять наблюдателя
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
UITextView *tv = object;
//Center vertical alignment
CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0;
topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
mTextViewHeightConstraint.constant = tv.contentSize.height;
[UIView animateWithDuration:0.2 animations:^{
[self.view layoutIfNeeded];
}];
}
-
если вы хотите, чтобы textviewHeight увеличивалось через некоторое время во время ввода, выполните это и установите делегат textview для себя.
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if(range.length + range.location > textView.text.length)
{
return NO;
}
NSUInteger newLength = [textView.text length] + [text length] - range.length;
return (newLength > 100) ? NO : YES;
}
Ответ 8
Если вашему textView
разрешено расти так же высоко, как и контенту, тогда
textView.isScrollEnabled = false
должен просто работать с autolayout.
Если вы хотите оставить textView
для textView
, вам нужно добавить дополнительное ограничение высоты,
internal lazy var textViewHeightConstraint: NSLayoutConstraint = {
let constraint = self.textView.heightAnchor.constraint(equalToConstant: 0)
constraint.priority = .defaultHigh
return constraint
}()
public override func layoutSubviews() {
super.layoutSubviews()
// Assuming there is width constraint setup on the textView.
let targetSize = CGSize(width: textView.frame.width, height: CGFloat(MAXFLOAT))
textViewHeightConstraint.constant = textView.sizeThatFits(targetSize).height
}
Причина переопределения layoutSubviews()
состоит в том, чтобы убедиться, что textView правильно выложен по горизонтали, поэтому мы можем рассчитывать на ширину для вычисления высоты.
Поскольку ограничение по высоте имеет более низкий приоритет, если оно занимает свободное место вертикально, фактическая высота textView
будет меньше, чем contentSize
. И textView будет прокручиваться.
Ответ 9
работает
func textViewDidChange(_ textView: UITextView) {
let fixedWidth = textviewconclusion.frame.size.width
textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
let newSize = textviewconclusion.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
var newFrame = textviewconclusion.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textviewconclusion.frame = newFrame
}
Ответ 10
SWIFT 4
Изменить размер при наборе
UITextViewDelegate
func textViewDidChange(_ textView: UITextView) {
yourTextView.translatesAutoresizingMaskIntoConstraints = true
yourTextView.sizeToFit()
yourTextView.isScrollEnabled = false
let calHeight = yourTextView.frame.size.height
yourTextView.frame = CGRect(x: 16, y: 193, width: self.view.frame.size.width - 32, height: calHeight)
}
Изменить размер при загрузке
func textViewNotasChange(arg : UITextView) {
arg.translatesAutoresizingMaskIntoConstraints = true
arg.sizeToFit()
arg.isScrollEnabled = false
let calHeight = arg.frame.size.height
arg.frame = CGRect(x: 16, y: 40, width: self.view.frame.size.width - 32, height: calHeight)
}
Вызовите функцию второй опции следующим образом:
textViewNotasChange(arg: yourTextView)
Ответ 11
В моем проекте диспетчер представлений задействован с множеством Constraints и StackView, и я устанавливал высоту TextView как ограничение и менялся в зависимости от значения textView.contentSize.height.
step1: получить выход IB
@IBOutlet weak var textViewHeight: NSLayoutConstraint!
step2: используйте метод делегирования ниже.
extension NewPostViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
textViewHeight.constant = self.textView.contentSize.height + 10
}
}
Ответ 12
Лучше, но быстро 4 добавить как расширение:
extension UITextView {
func resizeForHeight(){
self.translatesAutoresizingMaskIntoConstraints = true
self.sizeToFit()
self.isScrollEnabled = false
}
}
Ответ 13
Свифт 4+
Это очень легко с autolayout ! Я объясню самый простой вариант использования. Допустим, в вашем UITableViewCell
есть только UITextView
.
-
textView
к contentView
с ограничениями. - Отключите прокрутку для
textView
. - Обновите
tableView
в textViewDidChange
.
(Вы можете сделать последний шаг двумя способами - либо передать экземпляр tableView в ячейку, либо установить делегат textView на свой контроллер представления, реализовать textViewDidChange
делегат textViewDidChange
и обновить представление таблицы.)
Все это!
class TextViewCell: UITableViewCell {
//MARK: UI Element(s)
/// Reference of the parent table view so that it can be updated
var tableView: UITableView!
lazy var textView: UITextView = {
let textView = UITextView()
textView.isScrollEnabled = false
// Other textView properties
return textView
}()
//MARK: Padding Variable(s)
let padding: CGFloat = 50
//MARK: Initializer(s)
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubviews()
addConstraints()
textView.becomeFirstResponder()
}
//MARK: Helper Method(s)
func addSubviews() {
contentView.addSubview(textView)
}
func addConstraints() {
textView.leadingAnchor .constraint(equalTo: contentView.leadingAnchor, constant: padding).isActive = true
textView.trailingAnchor .constraint(equalTo: contentView.trailingAnchor, constant: -padding).isActive = true
textView.topAnchor .constraint(equalTo: contentView.topAnchor, constant: padding).isActive = true
textView.bottomAnchor .constraint(equalTo: contentView.bottomAnchor, constant: -padding).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension TextViewCell: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
Проверьте мой репо для полной реализации.
Ответ 14
Вот два подводных textView.textContainer.maximumNumberOfLines = 10
в iOS 8.3, когда вы textView.textContainer.maximumNumberOfLines = 10
с textView.textContainer.maximumNumberOfLines = 10
Обратитесь к моему тексту, пожалуйста.
textView.attributedText = originalContent
let lineLimit = 10
textView.isEditable = true
textView.isScrollEnabled = false
textView.textContainerInset = .zero // default is (8, 0, 8, 0)
textView.textContainer.maximumNumberOfLines = lineLimit // Important condition
textView.textContainer.lineBreakMode = .byTruncatingTail
// two incomplete methods, which do NOT work in iOS 8.3
// size.width可能比maxSize.width小 ————遗憾的是 iOS 8.3 上此方法无视maximumNumberOfLines参数,所以得借助于UILabel
// size.width may be less than maxSize.width, ---- Do NOT work in iOS 8.3, which disregards textView.textContainer.maximumNumberOfLines
// let size = textView.sizeThatFits(maxSize)
// 遗憾的是 iOS 8.3 上此方法失效了,得借助于UILabel
// Does not work in iOS 8.3
// let size = textView.layoutManager.usedRectForTextContainer(textView.textContainer).size
// Suggested method: use a temperary label to get its size
let label = UILabel(); label.attributedText = originalContent
let size = label.textRect(forBounds: CGRect(origin: .zero, size: maxSize), limitedToNumberOfLines: lineLimit).size
textView.frame.size = size
Ответ 15
1 Добавьте наблюдателя в длину содержимого текстового поля
yourTextView.addObserver(self, forKeyPath: "contentSize", options: (NSKeyValueObservingOptions.new), context: nil);
2 Внедрение наблюдателя
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
let tv = object as! UITextView;
var topCorrect = (tv.bounds.size.height - tv.contentSize.height * tv.zoomScale)/2.0;
topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
tv.contentOffset.x = 0;
tv.contentOffset.y = -topCorrect;
self.yourTextView.contentSize.height = tv.contentSize.height;
UIView.animate(withDuration: 0.2, animations: {
self.view.layoutIfNeeded();
});
}
Ответ 16
Вы можете сделать это с IB.
-
Создайте выход из ограничения высоты UITextView.
-
Унаследуйте свой UIViewController от UITextViewDelegate
-
затем
'
func textViewDidChange(_ textView: UITextView) {
// calculate text height
let constraintRect = CGSize(width: textView.frame.width,
height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect,
options: .usesLineFragmentOrigin,
attributes: [.font: textView.font],
context: nil)
let height = ceil(boundingBox.height)
// textViewHeightConstraint - your height constraint outlet from IB
if height > textViewHeightConstraint.constant {
textViewHeightConstraint.constant = height
UIView.animate(withDuration: 0.3, animations: {
self.view.layoutIfNeeded()
})
}
}'
Ответ 17
Этот ответ может быть поздно, но я надеюсь, что это кому-то поможет.
Для меня эти 2 строки кода работали:
textView.isScrollEnabled = false
textView.sizeToFit()
Но не устанавливайте ограничение высоты для вашего Textview