Marco
Marco

Reputation: 1061

How to use Swift - Autocomplete in textView

I have a textView where user can add comments and mention to other users. I've build a function which is triggered when the user type the sign "@". So basically as in Instagram or Facebook when the user types "@" a tableview appears and show the user suggestions. Here's my function:

func suggestUser() {
    if let searchText = postTextField.text {
        let words = searchText.components(separatedBy: .whitespacesAndNewlines)
        for var word in words {
            if word.hasPrefix("@") {
                word = word.trimmingCharacters(in: .punctuationCharacters)
                let userToSearch = String(word.dropFirst())
                self.viewContainerForTableView.isHidden = false
                self.suggestedUsers.removeAll()
                self.tableView.reloadData()
                Api.User.queryUsersByMentionName(WithText: userToSearch, completion: { (user) in
                    if !self.suggestedUsers.contains(where: { $0.id == user.id }) {
                        self.suggestedUsers.append(user)
                    }
                    self.tableView.reloadData()
                })
            } else {
                self.viewContainerForTableView.isHidden = true
            }
        }
    }
}

I have two issue: 1) When the user clicks on the suggested user in the tableview, how can i remove the text he already typed and add the one he selected? Let me give you an example:

If a user types @jan in the tableView appears janedoe. When the user click on the suggested name in table view how can i remove jan and add janedoe?

Here's my code for the didSelectRowAt

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let username = suggestedUsers[indexPath.row].username
    let usernameToAppend = username.components(separatedBy: .whitespacesAndNewlines).joined()
     postTextField.text.append("\(usernameToAppend)")
}

2) Is there a way to check if an user is already typed in the textView and so not displaying it in the tableview?

Thank you!

Upvotes: 2

Views: 1429

Answers (1)

Marco
Marco

Reputation: 1061

After an entire day of trying i Think I've found a solution... Hopefully...

so I have created an extension for my textView:

extension UITextView {

var currentWord : String? {

    let beginning = beginningOfDocument

    if let start = position(from: beginning, offset: selectedRange.location),
        let end = position(from: start, offset: selectedRange.length) {

        let textRange = tokenizer.rangeEnclosingPosition(end, with: .word, inDirection: 1)

        if let textRange = textRange {
            return text(in: textRange)
        }
    }
    return nil
  }
}

Then in my didSelectRowAt i have:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let username = suggestedUsers[indexPath.row].username
    let usernameToAppend = username.components(separatedBy: .whitespacesAndNewlines).joined()
    let currentWord = postTextField.currentWord
    if currentWord != nil && currentWord != "@"  {
        if let countIndex = currentWord?.count {
            let count = Int(countIndex)
            let startPosition = postTextField.selectedTextRange?.start
            let endPosition = postTextField.position(from: startPosition!, offset: -count)
            postTextField.selectedTextRange = postTextField.textRange(from: startPosition!, to: endPosition!)
            if let range = postTextField.selectedTextRange {
                postTextField.replace(range, withText: usernameToAppend)
            }
        }
    } else if currentWord == "@" {
        if let range = postTextField.selectedTextRange {
            if range.start == range.end {
                postTextField.replace(range, withText: usernameToAppend)
            }
        }
    }
  }
}

Upvotes: 1

Related Questions