0

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.

  • The same question already asked here :- https://stackoverflow.com/questions/29587912/how-to-create-a-new-line-by-tapping-the-return-key-in-uitextview-ios – Shabnam Siddiqui Dec 22 '21 at 15:52
  • 4 consecutive empty lines or just 4 empty lines anywhere in the body of the text? – trndjc Dec 22 '21 at 16:08
  • Consecutive @liquid – Jamie Lender Dec 22 '21 at 16:15
  • Keep in mind that if the user pastes a block of text with 5 consecutive empty lines, you must handle that case separately. In that case I would maybe check if `text` contains `"\n\n\n\n\n"`, or something like that, before returning a true or false. – trndjc Dec 22 '21 at 17:11

2 Answers2

0

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)
}
Bjorn B.
  • 506
  • 3
  • 10
0

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
}
trndjc
  • 11,654
  • 3
  • 38
  • 51