title: How to created the feature like Instagram and twitter to mention users and hashtags?
body: <p>When user type &quot;@&quot; in textview then it will display the list of the users and from that list user can select the any one.Same for the Hastag.I able to detect the &quot;@&quot; and &quot;#&quot; and open the list accordingly.I got the issue when user edit the text in the textview like remove or add the text in the textview in that case my logic not work properly. I have stored the index and length of the selected user and make it attributed text but when user edit the text the index will update and my logic goes wrong. Please give the solution for mentions.</p>
  <p>I used some code from this : <a href="https://github.com/omar14/OEMentions" rel="nofollow noreferrer">https://github.com/omar14/OEMentions</a></p>
  <pre><code>override func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -&gt; Bool {
      
      
          let str = String(textView.text)
          var lastCharacter = &quot;nothing&quot;
          
          if !str.isEmpty &amp;&amp; range.location != 0{
              lastCharacter = String(str[str.index(before: str.endIndex)])
          }
          
          // Check if there is mentions
          if mentionsIndexes.count != 0 {
              
              for item in mentionsIndexes {
                  
                  if case item.index ... item.index+item.length = range.location {
                      // If start typing within a mention rang delete that name:
                      
                     textView.replace(textView.textRangeFromNSRange(range: NSMakeRange(item.index, item.length))!, withText: &quot;&quot;)
                      
                      mentionsIndexes.removeAll(where: {($0.index == item.index)})
                      
                  }
                  
              }
          }
          
          if isMentioning {
              if text == &quot; &quot; || (text.count == 0 &amp;&amp;  self.mentionQuery == &quot;&quot;){ // If Space or delete the &quot;@&quot;
                  self.mentionQuery = &quot;&quot;
                  self.isMentioning = false
                  
                  self.arrayUsersForTag = []
                  
                  self.dropDown.hide()
                  
              }
              else if text.count == 0 {
                  self.mentionQuery.remove(at: self.mentionQuery.index(before: self.mentionQuery.endIndex))
                  
                  self.arrayUsersForTag = []
                  self.dropDown.hide()
                  
                  self.filterList(query: self.mentionQuery)
                  
              }
              else {
                  self.mentionQuery += text
                  self.filterList(query: self.mentionQuery)
              }
          } else {
              
              /* (Beginning of textView) OR (space then @) OR (Beginning of new line) */
              if text == self.mentionCharater &amp;&amp; ( range.location == 0 || lastCharacter == &quot; &quot; || lastCharacter == &quot;\n&quot;) {
                  
                  self.mentionQuery = &quot;&quot;
                  
                  self.isMentioning = true
                  self.startMentionIndex = range.location
                  self.filterList(query: self.mentionQuery)
                  
              }
          }
      
      
      return true
  }
  
  public func filterList(query: String) {
      
      arrayUsersForTag.removeAll()
      
      if query.isEmpty {
          arrayUsersForTag = self.withUsers
      }else{
          
          for object in withUsers {
              if object.fullname.lowercased().contains(query.lowercased()) {
                  arrayUsersForTag.append(object)
              }
          }
      }
      
      
      self.dropDown.dataSource = []
      for username in arrayUsersForTag {
          dropDown.dataSource.append(&quot;\(username.fullname)&quot;)
      }
      
      
      
      dropDown.show()
      
  }
  
  func dropDownSelection(){
      
      dropDown.selectionAction = { [weak self] (index, item) in
          
          self?.inputToolbar.contentView.textView.becomeFirstResponder()
          
          self?.addMentionToTextView(index)
          
        
          
          self?.dropDown.hide()
      }
  }
  
  
  // Add a mention name to the UITextView
  public func addMentionToTextView(_ arrayIndex : Int){
      
      let objUser = arrayUsersForTag[arrayIndex]
      
      let name = objUser.fullname
      
      let mention = &quot;@&quot;+name
      
      let objMention = MentionsIndexes()
      
      objMention.id = objUser.objectId
      
      objMention.index = self.startMentionIndex
      
      objMention.length = mention.count
      
      mentionsIndexes.append(objMention)
      
      if mentionQuery.isEmpty == false{
          
          let query = &quot;@&quot; + self.mentionQuery
          
          let range: Range&lt;String.Index&gt; = self.inputToolbar.contentView.textView.text.range(of:  query)!
          
          self.inputToolbar.contentView.textView.text.replaceSubrange(range, with: mention)
          
          
          let text =    self.inputToolbar.contentView.textView.text.appending(&quot; &quot;)
          
          self.inputToolbar.contentView.textView.text = text
          
      }else{
          
          let str = name
          
          let text =  self.inputToolbar.contentView.textView.text.appending(str).appending(&quot; &quot;)
          
          self.inputToolbar.contentView.textView.text = text
      }
      
      boldTheHastag()
      
      isMentioning = false
      self.mentionQuery = &quot;&quot;
      
  }
  
  func boldTheHastag(){
      
      // Add color attribute for the whole text
      
      if let theText = self.inputToolbar.contentView.textView.text{
          
          let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: theText)
          
          
          let count = self.inputToolbar.contentView.textView.text.count
          
          attributedString.addAttribute(NSAttributedString.Key.font, value: chatFont, range: NSMakeRange(0, count))
          
          
          // Add color &amp; font attributes for the mention
          for item in mentionsIndexes {
              
              attributedString.addAttribute(NSAttributedString.Key.font, value: boldFont, range: NSMakeRange(item.index, item.length))
          }
          
          
          
          //   attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: notMentionColor, range: NSMakeRange(count, 1))
          
          self.inputToolbar.contentView.textView.attributedText = attributedString
      }
  }
  </code></pre>
  <p>This code working fine for the normal scenario but if I removed the previously added mention and then try to add mention again then app will crash.</p>
  <p>If I delete or add some word in the textview then the index of the text will updated now how I can update the &quot;index&quot; value of each elements of array mentionsIndexes.</p>
  <p>If any other solution for mention users with &quot;@&quot; in app like Instagram is available please provide it.</p>