tags:

views:

2759

answers:

2

I am trying to limit the text input into a UITextView in cocoa-touch. I really want to limit the amount of rows rather than the number of characters. So far I have this to count the amount of rows:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@"\n"]) {
     rows++;
    }
    NSLog(@"Rows: %i", rows);
    return YES;
}

However this doesn't work if the line is automatically wrapped rather than the user pressing the return key. Is there a way to check if the text was wrapped similar to checking for "\n"?

Thanks.

+1  A: 

Are you trying to keep the text from scrolling the field? If so, you can easily use the NSString -stringWithFont:forWidth:lineBreakMode: to get the metrics of the current text in the field and see if that's a sub-rect of the bounds of the text field.

If you really want to limit it to a specific number of rows, you could try the same thing, and dividing the height by the text field font's leading property. In theory that will give you the number of rows, but there's no documentation to back this up, just experimentation.

If neither of those work for you, you're probably going to have to drop down to CoreGraphics, but I have never used CoreGraphics's text-drawing functions so I can't give you advice there. However, I expect either of the first two solutions should work just fine.

Kevin Ballard
+2  A: 

Unfortunately, using NSString -stringWithFont:forWidth:lineBreakMode: doesn't work - which ever wrap mode you choose, the text wraps with a width that is less than the current width, and the height becomes 0 on any overflow lines. To get a real figure, fit the string into a frame that is taller than the one you need - then you'll get a height that is greater than your actual height.

Note my fudge in this (subtracting 15 from the width). This might be something to do with my views (I have one within another), so you might not need it.

- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString*)aText
{
NSString* newText = [aTextView.text stringByReplacingCharactersInRange:aRange withString:aText];

// TODO - find out why the size of the string is smaller than the actual width, so that you get extra, wrapped characters unless you take something off
CGSize tallerSize = CGSizeMake(aTextView.frame.size.width-15,aTextView.frame.size.height*2); // pretend there's more vertical space to get that extra line to check on
CGSize newSize = [newText sizeWithFont:aTextView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];

if (newSize.height > aTextView.frame.size.height)
    {
    [myAppDelegate beep];
    return NO;
    }
else
    return YES;

}

Jane Sales