Home > OS >  How can I disable the return key in a UITextView based on the number of empty rows in the UITextView
How can I disable the return key in a UITextView based on the number of empty rows in the UITextView

Time:12-23

Both TikTok & Instagram (iOS) have a mechanism built into their edit profile biography code which enables the user to use the return key and create separation lines in user's profile biographies. However, after a certain number of lines returned with no text in the lines, they prevent the user from using the return key again.

How can one do this?

I understand how to prevent the return key from being used if the present line the cursor is on is empty, using the following:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        
  guard text.rangeOfCharacter(from: CharacterSet.newlines) == nil else {
    return false
  }
  return true

Moreover, I need help figuring out how to detect, for example, that 4 lines are empty, and stating that if 4 lines are empty, preventing the user from using the return key.

CodePudding user response:

This may need fine tuning for edge cases but this would be my starting point for sure. The idea is to check the last 4 inputs into the text view with the current input and decide what to do with it. This particular code would prevent the user from creating a fourth consecutive empty line.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "\n",
       textView.text.hasSuffix("\n\n\n\n") {
        return false
    }
    return true
}

CodePudding user response:

I am not completely sure I have understood your question correctly. But let me try to help.

A UITextView has a text property that you can read. Then, if a user enters a new character/inserts new text (make sure to test this with copy-pasting text), you could check whether the last three characters of the text are newlines or not. If so, and the user is trying to add another newline, you know to return false.

This would look like this:

let lastThreeCharacters = textView.text.suffix(3)

let lastThreeAreNewlines = (lastThreeCharacters.count == 3) && lastThreeCharacters.allSatisfy( {$0.isNewline} ) // Returns true if the last 3 characters are newlines

You'd need to implement some additional checks. Is the character that's going to be inserted a newline? If the user pastes text, will the last 4 characters be newlines?

Another method would be to make use of another method of the UITextViewDelegate. You could also implement textViewDidChange(_:), which is called after a user has changed the text. Then, check if (and where) the text contains four new lines and replace them with empty characters.

This would look something like this (taken from here):

func textViewDidChange(_ textView: UITextView) {
    // Avoid new lines also at the beginning
    textView.text = textView.text.replacingOccurrences(of: "^\n", with: "", options: .regularExpression)
    // Avoids 4 or more new lines after some text
    textView.text = textView.text.replacingOccurrences(of: "\n{4,}", with: "\n\n\n", options: .regularExpression)
}
  • Related