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.
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
}
}
You need to get the height of the text, not the width. Use either sizeWithFont:constrainedToSize:lineBreakMode:
(if you need to support iOS 6 or earlier) or use boundingRectWithSize:options:attributes:context:
if you only support iOS 7.
Swift 3
The accepted answer and the swift version works fine, but here is a Swift 3 version for the lazy people out there.
class CustomViewController: UIViewController, UITextViewDelegate {
let textView = UITextView(frame: .zero)
var previousRect = CGRect.zero
override func viewDidLoad(){
textView.frame = CGRect(
x: 20,
y: 0,
width: view.frame.width,
height: 50
)
textView.delegate = self
view.addSubview(textView)
}
func textViewDidChange(_ textView: UITextView) {
let pos = textView.endOfDocument
let currentRect = textView.caretRect(for: pos)
if previousRect != CGRect.zero {
if currentRect.origin.y > previousRect.origin.y {
print("new line")
}
}
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;
}
SWIFT 5
Lets not overcomplicate things.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
// return pressed
}
}
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.