Проблема с смайликами в TextView в Swift - PullRequest
3 голосов
/ 26 февраля 2020

Я использую приведенный ниже код для получения позиции курсора, когда пользователь вводит что-то в 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)
    }
}

Вариант использования: попытка реализовать хэштеги, аналогичные Instagram.

Подход : есть textView, и я добавил tableView под ним. TableView получает данные из вызова API на основе пользовательского ввода в textView. Например, если пользователь вводит #a, я показываю, что tableView и tableView загружаются с предложениями, такими как (#abc,#abcd, et c) из вызова API. Пользователь может выбрать строку и после выбора я скрываю tableView. Он отлично работает, когда пользователь вводит хэштеги между текстом типа #abc #insta и говорит, что если пользователь пытается ввести #ba между этим #abc #insta, он прекрасно вставляется после того, как пользователь выбирает предложение из tableView (например, #abc#bat#insta)

Проблема : Когда у меня есть смайлики, текст заменяет смайлики. Например, если пользователь вводит emoi # a, он получит список, начинающийся с #a (например, #abc,#ab et c), а теперь, если пользователь выберет #abc, он заполняет textView как #abc#a и смайлики исчезают. Я не вижу решения этой проблемы ни в одном из репозиториев Github. Кто-нибудь сталкивался с подобной проблемой?

...