Detect moment when newline starts in UITextView
Solution 1
This is how I would do it:
- Get the
UITextPosition
of the last character. - Call
caretRectForPosition
on yourUITextView
. - Create a
CGRect
variable and initially storeCGRectZero
in it. - In your
textViewDidChange:
method, callcaretRectForPosition:
by passing theUITextPosition
. - Compare it with the current value stored in the
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.
Solution 2
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
}
Solution 3
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
}
Solution 4
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;
}
Solution 5
SWIFT 4
If you don't want to use previousRect. Let's try this:
func textViewDidChange(_ textView: UITextView) {
let pos = textView.endOfDocument
let currentRect = textView.caretRect(for: pos)
if (currentRect.origin.y == -1 || currentRect.origin.y == CGFloat.infinity){
print("Yeah!, I've gone to a new line")
//-1 for new line with a char, infinity is new line with a space
}
}
Related videos on Youtube
mriddi
Updated on September 26, 2022Comments
-
mriddi over 1 year
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. -
mriddi over 10 yearsJust IOS7. Plz more details about using second one
-
rmaddy over 10 yearsLook at the docs. It's similar to the
sizeWithAttributes:
method you were using. You just need to pass in a size. Pass in a size with the desired width and a really large height. The returned size will be the same with but with the needed height to fit the text in the width. -
n00bProgrammer over 10 years@mriddi. I have given you a skeletal structure. You will have to add conditions as per your need. For instance, editing code in the middle of your text, or replacing words or characters.
-
rmaddy over 10 yearsThere are cases where this won't work. What about when the user pastes in text and the caret position is moved in the process?
-
n00bProgrammer over 10 yearsHence i mentioned that conditions have to be added.
-
Markus over 8 yearsPlease can anybody help me with the following question? If the user writes bulleted text (multiple line breaks) in UITextView, how to detect the total number of line breaks?
-
Nikhil Manapure almost 7 yearsWill this help if textView's text is set programmatically?
-
n00bProgrammer almost 7 years@NikhilManapure, sure. Just make sure you call the relevant code after you're done setting the text. Setting text programmatically does not call the delegate method (I think, though I'm unsure).
-
JP Aquino about 6 yearsThis only works if user presses return key, not if the new line starts because it reached the end of the previous line.
-
Saifan Nadaf over 4 yearsin which case u get currentRect.origin.y == -1 ??