I try to detect when carriage goes at new line in UITextView. I can detect it by comparison total later width with UITextView width:
CGSize size = [textView.text sizeWithAttributes:textView.typingAttributes];
if(size.width > textView.bounds.size.width)
NSLog (@"New line");
But it dose not work proper way because -sizeWithAttributes:textView
returns only width of letters without indentation width. Help please solve this.
This is how I would do it:
UITextPosition
of the last character.caretRectForPosition
on your UITextView
.CGRect
variable and initially store CGRectZero
in it.textViewDidChange:
method, call caretRectForPosition:
by passing the UITextPosition
.CGRect
variable. If the new y-origin of the caretRect is greater than the last one, it means a new line has been reached.Sample code:
CGRect previousRect = CGRectZero;
- (void)textViewDidChange:(UITextView *)textView{
UITextPosition* pos = yourTextView.endOfDocument;//explore others like beginningOfDocument if you want to customize the behaviour
CGRect currentRect = [yourTextView caretRectForPosition:pos];
if (currentRect.origin.y > previousRect.origin.y){
//new line reached, write your code
}
previousRect = currentRect;
}
Also, you should read the documentation for UITextInput
protocol reference here. It is magical, I'm telling you.
Let me know if you have any other issues with this.
For Swift use this
previousRect = CGRectZero
func textViewDidChange(textView: UITextView) {
var pos = textView.endOfDocument
var currentRect = textView.caretRectForPosition(pos)
if(currentRect.origin.y > previousRect?.origin.y){
//new line reached, write your code
}
previousRect = currentRect
}
answer of @n00bProgrammer in Swift-4
with more precise line break detection.
@n00bProgrammer answer is perfect except one thing it reacts differently when the user starts typing in a first line, it presents that Started New Line
too.
Overcoming issue, here is the refined code
var previousRect = CGRect.zero
func textViewDidChange(_ textView: UITextView) {
let pos = textView.endOfDocument
let currentRect = textView.caretRect(for: pos)
self.previousRect = self.previousRect.origin.y == 0.0 ? currentRect : self.previousRect
if currentRect.origin.y > self.previousRect.origin.y {
//new line reached, write your code
print("Started New Line")
}
self.previousRect = currentRect
}
You can use the UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText: (NSString *)text
{
BOOL newLine = [text isEqualToString:@"\n"];
if(newLine)
{
NSLog(@"User started a new line");
}
return YES;
}
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