我想知道如何限制用户在编辑UITextField时可以输入的LINES数量(不是其他问题中询问的字符)。
理想情况下,我想将输入限制为最大。10行。
我需要从哪里开始?我可以用一种方法吗?在
- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView
我想知道如何限制用户在编辑UITextField时可以输入的LINES数量(不是其他问题中询问的字符)。
理想情况下,我想将输入限制为最大。10行。
我需要从哪里开始?我可以用一种方法吗?在
- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView
Answers:
您有正确的想法,但有错误的方法。textView:shouldChangeTextInRange:replacementText:
每当文本更改时都会被调用;您可以使用其text
属性访问文本视图的当前内容,还可以根据传递的范围和替换文本来构造新内容[textView.text stringByReplacingCharactersInRange:range withString:replacementText]
。然后,您可以计算行数并返回YES允许更改,或者返回NO拒绝更改。
UITextView
是的子类,UIScrollView
并且具有pagingEnabled
属性。
Maciek Czarnik的答案对我不起作用,但是它使我了解到该怎么做。
iOS 7以上
迅速
textView.textContainer.maximumNumberOfLines = 10
textView.textContainer.lineBreakMode = .byTruncatingTail
对象
textView.textContainer.maximumNumberOfLines = 10;
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
textView.textContainer.lineBreakMode = .ByTruncatingTail
也许可以帮上忙(iOS 7+):
textView.textContainer.maximumNumberOfLines = 10;
[textView.layoutManager textContainerChangedGeometry:textView.textContainer];
我猜连第一行都可以解决,但不行。。。也许这是SDK中的错误
Maciek Czarnik的答案似乎对我不起作用,即使在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 4.2 / Swift 5中Numereyes答案的改进版本
我做了一些扩展,以便可以重用代码。我正在使用While-Loop检查尺寸是否合适。当用户一次粘贴很多文本时,这也适用。
extension UITextView {
var numberOfCurrentlyDisplayedLines: Int {
let size = systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
//for Swift <=4.0, replace with next line:
//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)
}
斯威夫特4
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
}
如果您还想限制字符:
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
if(text == "\n") {
return linesAfterChange <= textView.textContainer.maximumNumberOfLines
}
let newText = (textView.text as NSString).replacingCharacters(in: range, with: text)
let numberOfChars = newText.count
return numberOfChars <= 30 // 30 characters limit
}
}
不要忘记添加您希望限制的行数viewDidLoad
:
txtView.textContainer.maximumNumberOfLines = 2
给出的其他解决方案不能解决与在末尾创建最后一行有关的问题(在问题的情况下为第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
}
注意:此解决方案无法处理最后一行太长而无法显示的情况(文本将隐藏在UITextView的最右侧)。
与其他答案类似,但可以直接从Storyboard使用,而无需子类化:
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
}
}
}