设置UITextView中行数的最大值

7
我希望限制我的iPad应用程序用户在输出PDF时最多只能输入20行。用户输入文本到UITextView(如下所示),然后将其转换为PDF文档。
我意识到,我将不得不根据输入的文本进行一些计算。这里有没有任何可以帮助我的方法?textFieldDidEndEditing仅允许我在输入之后检查。
此外,如果这样做会简单得多,是否有一种限制UITextField可以使用的行数的方法?

2
你可以使用文本框的 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 代理方法,如果用户即将输入的字符会使文本过长,则返回 NO。然而,我不知道有什么好的方法来确定这一点。 - Jesse Rusak
4个回答

11

你接近了textFieldDidEndEditing委托方法。

然而,更好的方法是响应textView:shouldChangeTextInRange:replacementText:委托方法,然后查看即将发生的更改是否会导致超过允许的行数。

以下是如何实现的示例:

- (BOOL) textView:(UITextView *)textView
    shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    static const NSUInteger MAX_NUMBER_OF_LINES_ALLOWED = 3;

    NSMutableString *t = [NSMutableString stringWithString:
        self.textView.text];
    [t replaceCharactersInRange: range withString: text];

    NSUInteger numberOfLines = 0;
    for (NSUInteger i = 0; i < t.length; i++) {
        if ([[NSCharacterSet newlineCharacterSet]
                characterIsMember: [t characterAtIndex: i]]) {
            numberOfLines++;
        }
    }

    return (numberOfLines < MAX_NUMBER_OF_LINES_ALLOWED);
}

我在https://github.com/st3fan/StackOverflow/tree/master/TextViewWithLineLimit上提供了一个完整的示例,用于测试iOS 7.0.2下的TextView行数限制。祝使用愉快!


6
然而,这并不能解决换行的问题,因为它只是查找换行符。 - Jesse Rusak
我刚刚看了一下,就像Jesse所说的那样,这并没有考虑到一个长的换行文本。尽管如此,它确实向我展示了如何在用户输入时检查文本 - 谢谢。 - RGriffiths

4
以下内容支持'\n' + 换行符的换行。
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.AutoresizingMask   = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        self.AutocorrectionType = UITextAutocorrectionTypeNo;
        self.KeyboardAppearance = UIKeyboardAppearanceAlert;
        self.font               = [UIFont fontWithName:@"Avenir" size:14];

        self.maximumNumberOfLinesAllowed = 4;

        self.delegate           = self;
    }

    return self;
}


- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString*)aText
{
    NSMutableString *t = [NSMutableString stringWithString: self.text];
    [t replaceCharactersInRange: aRange withString: aText];

    // First check for standard '\n' (newline) type characters.
    NSUInteger numberOfLines = 0;
    for (NSUInteger i = 0; i < t.length; i++) {
        if ([[NSCharacterSet newlineCharacterSet] characterIsMember: [t characterAtIndex: i]]) {
            numberOfLines++;
        }
    }

    if (numberOfLines >= self.maximumNumberOfLinesAllowed)
        return NO;


    // Now check for word wrapping onto newline.
    NSAttributedString *t2 = [[NSAttributedString alloc]
                             initWithString:[NSMutableString stringWithString:t] attributes:@{NSFontAttributeName:self.font}];

    __block NSInteger lineCount = 0;

    CGFloat maxWidth   = self.frame.size.width;
    NSLog(@"maxWidth = %.02f", maxWidth);

    NSTextContainer *tc = [[NSTextContainer alloc] initWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX)];
    NSLayoutManager *lm = [[NSLayoutManager alloc] init];
    NSTextStorage   *ts = [[NSTextStorage alloc] initWithAttributedString:t2];
    [ts addLayoutManager:lm];
    [lm addTextContainer:tc];
    [lm enumerateLineFragmentsForGlyphRange:NSMakeRange(0,lm.numberOfGlyphs)
                                 usingBlock:^(CGRect rect,
                                              CGRect usedRect,
                                              NSTextContainer *textContainer,
                                              NSRange glyphRange,
                                              BOOL *stop)
     {
         lineCount++;
     }];

//    NSLog(@"%d", lineCount);

    return (lineCount <= self.maximumNumberOfLinesAllowed);

}

你为什么要设置 self.AutocorrectionType = UITextAutocorrectionTypeNo; - j b
不是真的。它只是这样。 :) - Sebastian Dwornik
代码运行良好 - 谢谢。然而,我发现了一个边缘情况:1.将最大行数设置为两行。2.输入文本直到溢出到第二行的末尾。3.按“Return”键。换行符将被允许并进入第三行!哎呀! - fatuhoku

2
为了限制UITextView中的行数,我只需执行以下操作:
在下面的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];
    }
}

这种方法不可靠,因为它假定你添加的文本是在末尾。如果你把光标放在字符串中间,它会允许你添加任意数量的回车。 - ToddH

-1

更加容易的方法是这样做:

Swift:

textView.textContainer.maximumNumberOfLines = 10;
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;

Obj-C:

textView.textContainer.maximumNumberOfLines = 10;
[textView.layoutManager textContainerChangedGeometry:textView.textContainer];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接