我想知道如何在编辑UITextField时限制用户输入的行数(而不是像其他问题中询问的字符数)。
理想情况下,我要将输入限制为最多10行。
我需要从哪里开始? 我是否需要使用方法来完成这个功能?
- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView
我想知道如何在编辑UITextField时限制用户输入的行数(而不是像其他问题中询问的字符数)。
理想情况下,我要将输入限制为最多10行。
我需要从哪里开始? 我是否需要使用方法来完成这个功能?
- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView
Maciek Czarnik的回答对我没用,但它让我知道该怎么做。
iOS 7以上
Swift
textView.textContainer.maximumNumberOfLines = 10
textView.textContainer.lineBreakMode = .byTruncatingTail
Objective-C
textView.textContainer.maximumNumberOfLines = 10;
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
textView.textContainer.lineBreakMode = .ByTruncatingTail
注:该翻译为技术性语言,仅供参考。 - App Dev Guy也许这可以帮助(适用于iOS 7+):
textView.textContainer.maximumNumberOfLines = 10;
[textView.layoutManager textContainerChangedGeometry:textView.textContainer];
我想即使是第一行也应该行得通,但实际上并没有...也许这是SDK的一个错误
textView:shouldChangeTextInRange:replacementText:
方法;您可以使用文本视图的text
属性访问文本视图的当前内容,并使用[textView.text stringByReplacingCharactersInRange:range withString:replacementText]
根据传递的范围和替换文本构建新内容。然后您可以计算行数,返回YES以允许更改或NO以拒绝更改。UITextView
是UIScrollView
的子类,因此具有pagingEnabled
属性。 - Anomie在 Swift 3.0
版本中:
self.textView.textContainer.maximumNumberOfLines = self.textViewNumberOflines
self.textView.textContainer.lineBreakMode = .byTruncatingTail
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];
}
}
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)
}
Swift 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
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
}
< p > < em > 注意: < /em > 这个解决方案不能处理最后一行太长无法显示的情况(文本将被隐藏在 UITextView 的右侧)。< /p >
与其他答案类似,但可以直接从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
}
}
}
请参考苹果文档:计算文本行数 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html
- (void)textViewDidChangeSelection:(UITextView *)textView{
NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index, numberOfGlyphs =
(unsigned)[layoutManager numberOfGlyphs];
NSRange lineRange;
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];
index = (unsigned)NSMaxRange(lineRange);
}
if(numberOfLines > 10){
self.textField.text = self.lastString;
}
}
处理 "\n"
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if([text containsString:@"\n"]){
NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index, numberOfGlyphs =
(unsigned)[layoutManager numberOfGlyphs];
NSRange lineRange;
for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];
index = (unsigned)NSMaxRange(lineRange);
}
NSLog(@"lines = %d",numberOfLines);
if(numberOfLines >= 10){
return NO;
}
}
self.lastString = textView.text;
return YES;
}