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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With