UITextView adding new line unintentionally?
One solution to solve this is when you implement the textFieldShouldReturn:
delegate method, be sure to return NO
, and not YES
. By returning NO
, the newline isn't passed on to the text field.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// move to next field or whatever you need
[myTextView becomeFirstResponder];
return NO;
}
UITextView Adding new line when becoming first responder
Great question and description. I had the exact same problem.
No answer on this thread solved it for me. Someone put a link in the comments (by @AndreiRadulescu) of another thread. an answer by @rmaddy on that thread solved it. His answer was:
One solution to solve this is when you implement the
textFieldShouldReturn: delegate method, be sure to return NO, and not
YES. By returning NO, the newline isn't passed on to the text field.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// move to next field or whatever you need
[myTextView becomeFirstResponder];
return NO;
}
In Swift:
//Dismisses keyboard upon tapping the return key
func textFieldShouldReturn(textField: UITextField) -> Bool {
txtTask.resignFirstResponder()
return false
}
How can I prevent a user from adding too many line breaks in a UITextView in Swift 5?
Here is my solution:
UPDATED WITH Matt Bart feedback
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == String(characterToCheck) /* \n, declared globally */ {
characterCounter += 1 // this was also declared as a global property
}
if text == "" {
let characters = Array(textView.text)
if characters.count >= range.location {
let deletedCharacter = characters[range.location]
if deletedCharacter == characterToCheck {
characterCounter -= 1
}
}
}
if characterCounter > 4 {
let newlineAC = UIAlertController(title: "Too many linebreaks", message: "Please go back and make your comment fit into a maximum of 5 lines", preferredStyle: .alert)
newlineAC.addAction(UIAlertAction(title: "OK", style: .default) { [weak self] (_) in
let currentText = textView.text ?? ""
guard let currentTextRange = Range(range, in: currentText) else { return }
self?.comments.text = currentText.replacingOccurrences(of: "\n", with: "@ ", range: currentTextRange)
})
present(newlineAC, animated: true, completion: { [weak self] in
self?.characterCounter -= 1
})
return false
} else {
return true
}
}
}
Also, declare characterToCheck
as a Character
instead of String
characterCounter
must start at 0
UITextView becomeFirstResponder() adds new line
Return false in textFieldShouldReturn
func textFieldShouldReturn(nameTextField: UITextField) -> Bool {
nameTextField.resignFirstResponder()
descriptionTextView.becomeFirstResponder()
return false
}
More details here
How to create a new line by tapping the return key in UITextView ios
You should implement delegate method with returning value NO (so on tapping "return" or "done" it will not close keyboard).
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
return NO;
}
and remove or change logic of next lines of code:
if (range.length == 0) {
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
}
So in textViewShouldEndEditing you can determine/calculate situations when you need to close keyboard (if you want to close - return YES, otherwise return - NO)
You can also change logic of
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
to
if (range.length == 0) {
if ([text isEqualToString:@"\n"]) {
textView.text = [NSString stringWithFormat:@"%@\n\t",textView.text];
return NO;
}
}
In this case when user will tap on action button on keyboard (like "return"). Textview will insert new line and additional tab in text.
I hope it will help you.
Check if text in UITextView went to new line due to word wrap
You can use the contentSize.height property of UITextView to determine how 'tall' your textview is. You can then divide by the lineHeight to figure out the number of lines. @nacho4d provided this nifty line of code that does just that:
int numLines = textView.contentSize.height/textView.font.lineHeight;
Refer to this question for more info:
How to read number of lines in uitextview
EDIT:
So you could do something like this inside -textViewDidChange: in order to check for a line change.
int numLines = textView.contentSize.height / textView.font.lineHeight;
if (numLines != numLinesInTextView){
numLinesInTextView = numLines;//numLinesInTextView is an instance variable
//then do whatever you need to do on line change
}
Swift 3 - Detecting new lines in UITextView
I solved the problem by myself, I will post the code below if someone need it (check comments in the code):
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 {
// Array of Strings
var currentLines = textView.text.components(separatedBy: "\n")
// Remove Blank Strings
currentLines = currentLines.filter{ $0 != "" }
//increase the counter counting how many items inside the array
counter = currentLines.count
}
}
previousRect = currentRect
}
How to insert line break at the end of specific line of UITextView
- Split the text into lines with
components(separatedBy: .newlines)
- Get the 5th line (at index 4!)
- Get the range of the line in the text with
range(of:)
- Insert the line break at the
upperBound
index of the range.
Related Topics
How Detect Swipe Gesture Direction
An Elegant Way to Ignore Any Errors Thrown by a Method
Resize the Screen When Keyboard Appears
How to Filter Firebase Data in Swift
How to Change the Color of Uipickerview Selector
How Can Split from String to Array by Chunks of Given Size
How to Make Generics in Collection Type Constraint
Cabasicanimation Resets to Initial Value After Animation Completes
How to Integrate Cocoapods with a Swift Project
How to Restrict Uitextfield to Take Only Numbers in Swift
Add Cocoapods to Tests Target Too
Xcode 4.3.2, Issue with Running on Simulator
Xcode 10 Build Fails with 'Command Compileswift Failed with a Nonzero Exit Code
Ckquery from Private Zone Returns Only First 100 Ckrecords from in Cloudkit
Is This Code Drawing at the Point or Pixel Level? How to Draw Retina Pixels
Swift: Failed to Assign Value to a Property of Protocol