Ограничить количество строк для UITextview
мне было интересно, как ограничить количество строк (а не символов, как задано в других вопросах), которые пользователь может ввести при редактировании UITextField.
В идеале, я хотел бы ограничить вход до макс. 10 линий.
С чего бы мне начать? Я делаю это с помощью метода? В
- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView
8 ответов:
у вас есть правильная идея, но неправильный метод.
textView:shouldChangeTextInRange:replacementText:вызывается каждый раз, когда текст будет меняться; вы можете получить доступ к текущему содержимому представления текста, используяtextсвойство, и вы можете построить новое содержимое из переданного диапазона и заменить текст на[textView.text stringByReplacingCharactersInRange:range withString:replacementText]. Затем вы можете подсчитать количество строк и вернуть да, чтобы разрешить изменение или нет, чтобы отклонить его.
Maciek Czarnik ответ не работал для меня, но это дало мне понимание, что делать.
iOS 7+
Свифт
textView.textContainer.maximumNumberOfLines = 10 textView.textContainer.lineBreakMode = .byTruncatingTailObjC
textView.textContainer.maximumNumberOfLines = 10; textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
возможно, это может помочь (iOS 7+):
textView.textContainer.maximumNumberOfLines = 10; [textView.layoutManager textContainerChangedGeometry:textView.textContainer];даже первая строка должна сделать трюк, я думаю, но не... Может быть, это ошибка в SDK
ответ Мацека Чарника, похоже, не работает для меня, даже в iOS7. Это дает мне странное поведение, я не знаю, почему.
что я делаю, чтобы ограничить количество строк в UITextView просто:
(проверено только в iOS7) в следующем методе UITextViewDelegate:
- (void)textViewDidChange:(UITextView *)textView { NSUInteger maxNumberOfLines = 5; NSUInteger numLines = textView.contentSize.height/textView.font.lineHeight; if (numLines > maxNumberOfLines) { textView.text = [textView.text substringToIndex:textView.text.length - 1]; } }
на
Swift 3.0версия:self.textView.textContainer.maximumNumberOfLines = self.textViewNumberOflines self.textView.textContainer.lineBreakMode = .byTruncatingTail
другие приведенные решения не решают проблему, связанную с последней строкой, создаваемой в конце (11-я строка в случае вопроса).
вот рабочее решение с
Swift 4.0& Xcode 9.0 beta (найдено на этот блог)class ViewController: UIViewController, UITextViewDelegate { @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self textView.textContainer.maximumNumberOfLines = 10 textView.textContainer.lineBreakMode = .byWordWrapping } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let existingLines = textView.text.components(separatedBy: CharacterSet.newlines) let newLines = text.components(separatedBy: CharacterSet.newlines) let linesAfterChange = existingLines.count + newLines.count - 1 return linesAfterChange <= textView.textContainer.maximumNumberOfLines }Nota bene: это решение не обрабатывает сценарий, в котором последняя строка слишком длинна для отображения (текст будет скрыт в дальней правой части UITextView).
похоже на другие ответы, но можно использовать непосредственно из раскадровки и без подклассов:
extension UITextView { @IBInspectable var maxNumberOfLines: NSInteger { set { textContainer.maximumNumberOfLines = maxNumberOfLines } get { return textContainer.maximumNumberOfLines } } @IBInspectable var lineBreakByTruncatingTail: Bool { set { if lineBreakByTruncatingTail { textContainer.lineBreakMode = .byTruncatingTail } } get { return textContainer.lineBreakMode == .byTruncatingTail } } }
вот улучшенная версия ответа Numereyes в Swift 4
Я сделал небольшое расширение, чтобы я мог повторно использовать код. Я использую цикл While, чтобы проверить, подходит ли размер. Это также работает, когда пользователь вставляет много текста сразу.
extension UITextView { var numberOfCurrentlyDisplayedLines: Int { let size = systemLayoutSizeFitting(UILayoutFittingCompressedSize) return Int(((size.height - layoutMargins.top - layoutMargins.bottom) / font!.lineHeight)) } /// Removes last characters until the given max. number of lines is reached func removeTextUntilSatisfying(maxNumberOfLines: Int) { while numberOfCurrentlyDisplayedLines > (maxNumberOfLines) { text = String(text.dropLast()) layoutIfNeeded() } } } // Use it in UITextView's delegate method: func textViewDidChange(_ textView: UITextView) { textView.removeTextUntilSatisfying(maxNumberOfLines: 10) }
Comments