Issue with emojis in TextView in Swift

Viewed 504

I’m using the below code to get the cursor position when the user types something in the textView.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

  inputChar = text
  inputRange = range
  inputIndex = inputRange?.upperBound
  self.presenter.hashtagDataArray.removeAll()
  if(text == "\n") {
    textView.resignFirstResponder()
    toggleTableView(toggle: true)
    return false
  }
  let str = (textView.text + text)
  if str.utf16.count <= MediaPostViewController.descCharacterLimits {
    return true
  }
  let numberOfChars = str.utf16.count
  lbbbl_DescCount.text = "\(textView.text.utf16.count)/\(MediaPostViewController.descCharacterLimits)"
  return (numberOfChars <= MediaPostViewController.descCharacterLimits) || (str.utf16.count < textView.text.utf16.count) 
}

func textViewDidChange(_ textView: UITextView) {
    var indexPosition : Int?
    updateCharacterCount()
    self.mainScrollView.isScrollEnabled = false

if textView.text != "" {

    inputIndex = (String(textView.text.utf16) as NSString?)?.substring(with: NSRange(location: 0, length: inputRange!.location)).count
    cursorPosition = inputIndex! + 1
    inputText = textView.text!
    textViewEndIndex = textView.text.unicodeScalars.endIndex.utf16Offset(in: textView.text)
    if #available(iOS 10.2, *) {
      inputText = textView.text.replaceEmoji(with: "@")
    } else {
     //Fallback on earlier versions
    }
    if inputChar == "" || inputChar == " "{
      indexPosition = cursorPosition!-2
    }
    else {
      indexPosition = cursorPosition!-1
    }
    guard let enteredText = inputText?.utf16.subString(from: 0, to: indexPosition!) else { return }
    guard let lastdelimiterposition = enteredText.lastIndexPosition(of: "#") else { return }

    hashwordstartIndex = lastdelimiterposition
    checkhashinword = inputText?.utf16.subString(from: lastdelimiterposition, to: indexPosition!)


    if inputChar == "" || inputChar == " "{
                    spaceCharactersCheck = 1
                 }
      if spaceCharactersCheck == 1{
        checkhashword = checkhashinword?.components(separatedBy: " ").filter({!$0.contains("#")}).joined(separator: " ")
        checkhashedword = checkhashinword?.components(separatedBy: " ").filter({$0.contains("#")}).joined(separator: " ")
        }
    if let checkhashinword = checkhashinword {
        if checkhashinword.utf16.count > 1 && !(checkhashinword.contains(" ")){
          self.presenter.returnHashTagsData((checkhashinword.utf16.subString(from: 1, to: checkhashinword.utf16.count-1))!)
        }
      }

    }
  else {
            self.toggleTableView(toggle: true)
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

      let rowSelected = tableView.cellForRow(at: indexPath)?.textLabel?.text
      var textViewValue : String?
      textViewValue = textView_Desc.text!
      let startIndex = String.Index(utf16Offset: hashwordstartIndex!, in: String(textViewValue!))
      let hashwordendIndex = String.Index(utf16Offset: inputIndex!, in: String(textViewValue!))
      let range = startIndex...hashwordendIndex
        if var strNewText = textViewValue?.components(separatedBy: "#") {
        if strNewText.count > 1 {
          if let textlabel = rowSelected {
                strNewText[strNewText.count - 1] = textlabel
          }
        }
        if var rowSelected = rowSelected {
            if let checkhashword = checkhashword
            {
              if checkhashword != ""
                {
                  rowSelected = rowSelected.appending(" ").appending(checkhashword).appending(String(checkhashedword!))
                }
            }

            if textViewValue != ""{
              if textViewEndIndex != inputIndex {
                    do {
                        if let result = textViewValue?.replaceSubrange(range, with: rowSelected)
                        {
                          print("result:\(result)")
                        }
                        else {
                            throw RangeException.notaValidRange
                           }
                      }
                    catch {

                       }
                  }
                }

              spaceCharactersCheck = 0
              checkhashword = ""
              checkhashedword = ""
        }

        let combinedText = strNewText.joined(separator: "#")//.appending(" ")

        if combinedText.count-1 > MediaPostViewController.descCharacterLimits {
          if textView_Desc.text.count-1 > MediaPostViewController.descCharacterLimits {
            toggleTableView(toggle: true)
            return
          }
        }
            if textViewEndIndex != inputIndex {
                    textView_Desc.text = textViewValue
                }
              else {
                  textView_Desc.text = combinedText.replacingOccurrences(of: "##", with: "#")
                }

          lbbbl_DescCount.text = "\(textView_Desc.text.count)/\(MediaPostViewController.descCharacterLimits)"
        }
        toggleTableView(toggle: true)
        self.hideScrollView.isHidden = false
        self.view.bringSubviewToFront(hideScrollView)
    }
}

Use case : Trying to implement hashtags similar to Instagram.

Approach: There is a textView and I’ve added a tableView beneath that. The tableView gets data from API call based on the user input in textView. For instance, if user types #a then I show the tableView and tableView is loaded with suggestions like (#abc,#abcd, etc) from API call. The user can select a row and after selection, I hide the tableView. It works perfectly fine when the user enters hashtags between a text like #abc #insta and say if the user tries to type #ba between this #abc #insta it gets perfectly inserted after user chooses a suggestion from tableView (like #abc#bat#insta)

Problem: When I have emojis the text replaces the emoji. For eg: if the user enters emoi#a then it will get a list starting with #a (like #abc,#ab etc) and now if the user selects #abc then it populates the textView like #abc#a and emoji disappears. I don’t see a solution to this problem in any Github repositories. Has anyone faced a similar problem?

0 Answers
Related