简体   繁体   中英

Limiting the number of lines within a UITextView

I'm well aware this question has been asked but I cannot find a valid answer. Using a combination of prior solutions I've come up with this code:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string
{
    int numLines = notesTextView.contentSize.height / notesTextView.font.lineHeight;
        if (numLines <= 8)
        {
            return true;
        }
        return false;
}

This does not work because the number of lines is counted prior to the additional text so we are still taken a line beyond what we want and are then trapped on it as no further editing is possible.

I've also tried solutions that detect "\\n" entries but this doesn't work either as we can reach new lines naturally without pressing return.

I also encountered this problem. None of the earlier solutions worked well for me. Here is my solution, hope: (iOS 7+ only!)

- (void)textViewDidChange:(UITextView *)textView
{
    NSLayoutManager *layoutManager = [textView layoutManager];
    NSUInteger numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs];
    NSRange lineRange;
    for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++)
    {
            (void) [layoutManager lineFragmentRectForGlyphAtIndex:index
                                               effectiveRange:&lineRange];
        index = NSMaxRange(lineRange);
    }

    if (numberOfLines > 3)
    {
        // roll back
        _labelField.text = _text;
    }
    else
    {
        // change accepted
        _text = _labelField.text;
    }
}

It uses an NSString ivar _text to be able to roll back after the text has been changed. This does not cause any flickering.

numberOfLines reference: https://developer.apple.com/library/mac/documentation/cocoa/conceptual/TextLayout/Tasks/CountLines.html#//apple_ref/doc/uid/20001810-CJBGBIBB

How about this:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string
{
    NSString *temp = [textView.text stringByReplacingCharactersInRange:range withString:string]
    CGSize size = [temp sizeWithFont:textView.font constrainedToSize:CGSizeMake(textView.frame.size.width,999) lineBreakMode:UILineBreakModeWordWrap];
    int numLines = size.height / textView.font.lineHeight;
    if (numLines <= 8)
    {
        return true;
    }
    return false;
}

Parse in the new text, then check the new text's size using the textView's information.

here is how i have done it in past, i hope it provide you with some help.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
{

// limit the number of lines in textview
NSString* newText = [mytextView.text stringByReplacingCharactersInRange:range withString:text];

// pretend there's more vertical space to get that extra line to check on
CGSize tallerSize = CGSizeMake(mytextView.frame.size.width-15, mytextView.frame.size.height*2); 

CGSize newSize = [newText sizeWithFont:mytextView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];

if (newSize.height > mytextView.frame.size.height)
{
    NSLog(@"two lines are full");
    return NO;
}


// dismiss keyboard and send comment
if([text isEqualToString:@"\n"]) {
    [mytextView resignFirstResponder];

    return NO;
}

return YES;
}

good luck.

Edit:

Ok try the following method and see if this works for you. Just change the number of lines to whatever number you want.

 (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@"n"]) {
        rows++;
    if(rows >= maxNumberOfLines){
        //Exit textview
         return NO;
        }
   }
  return YES;

Let me know if this works out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM