Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting autocomplete to work in swift

I am trying to implement autocompletion, but can't find an example that works in Swift. Below, I'm tring to convert Ray Wenderlich's autocompletion tutorial and example code from 2010. Finally, the code compiles, but the table containing possible completions does not appear, and I don't have the experience to see why it is not unhidden by shouldChangeCharactersInRange.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

@IBOutlet weak var textField: UITextField!
let autocompleteTableView = UITableView(frame: CGRectMake(0,80,320,120), style: UITableViewStyle.Plain)

var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    autocompleteTableView.delegate = self
    autocompleteTableView.dataSource = self
    autocompleteTableView.scrollEnabled = true
    autocompleteTableView.hidden = true
}

func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
    autocompleteTableView.hidden = false
    var substring = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)

    searchAutocompleteEntriesWithSubstring(substring)
    return true     // not sure about this - could be false
}

func searchAutocompleteEntriesWithSubstring(substring: String)
{
    autocompleteUrls.removeAll(keepCapacity: false)
    var indexOfPastUrls = 0

    for curString in pastUrls
    {
        let substringRange = curString.rangeOfString(curString)

        if (indexOfPastUrls  == 0)
        {
            autocompleteUrls.append(curString)
        }
        indexOfPastUrls = indexOfPastUrls + 1
    }
    autocompleteTableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return autocompleteUrls.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
    var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
    let index = indexPath.row as Int

    cell.textLabel.text = autocompleteUrls[index]
    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    textField.text = selectedCell.textLabel.text        
}
}
like image 218
DrWhat Avatar asked Nov 12 '14 11:11

DrWhat


3 Answers

Replace your searchAutocompleteEntriesWithSubstring function content with the one below. I hope it would help you.

func searchAutocompleteEntriesWithSubstring(substring: String)
{
    autocompleteUrls.removeAll(keepCapacity: false)

    for curString in pastUrls
    {
        var myString:NSString! = curString as NSString

        var substringRange :NSRange! = myString.rangeOfString(substring)

        if (substringRange.location  == 0)
        {
            autocompleteUrls.append(curString)
        }
    }

    autocompleteTableView.reloadData()
}
like image 97
Tamnna Avatar answered Nov 11 '22 05:11

Tamnna


The table was not appearing because the UITextField delegate was not to self in viewDidLoad. There was another final issue with the table not showing the autocompletion results, but this is also fixed. Ray Wenderlich's basic Objective-C autocompletion tutorial converted to Swift:

class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate,   UITableViewDataSource {

@IBOutlet weak var textField: UITextField!
@IBOutlet var autocompleteTableView: UITableView!

// @IBOutlet weak var autocompleteTableView = UITableView(frame: CGRectMake(0,80,320,120), style: UITableViewStyle.Plain)

var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    textField.delegate = self

    autocompleteTableView!.delegate = self
    autocompleteTableView!.dataSource = self
    autocompleteTableView!.scrollEnabled = true
    autocompleteTableView!.hidden = true
}

func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
    println("banana")
    autocompleteTableView!.hidden = false
    var substring = (self.textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)

    searchAutocompleteEntriesWithSubstring(substring)
    return true
}

func searchAutocompleteEntriesWithSubstring(substring: String)
{
    autocompleteUrls.removeAll(keepCapacity: false)
    println(substring)

    for curString in pastUrls
    {
        println(curString)
        var myString: NSString! = curString as NSString
        var substringRange: NSRange! = myString.rangeOfString(substring)
        if (substringRange.location == 0)
        {
            autocompleteUrls.append(curString)
        }
    }

    autocompleteTableView!.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return autocompleteUrls.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
    var cell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier) as? UITableViewCell

    if let tempo1 = cell
    {
        let index = indexPath.row as Int
        cell!.textLabel.text = autocompleteUrls[index]
    } else
    {
        cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: autoCompleteRowIdentifier)
    }
    return cell!
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
    textField.text = selectedCell.textLabel.text
}

}

like image 35
DrWhat Avatar answered Nov 11 '22 05:11

DrWhat


I put together a tutorial that is full of pictures on how to recreate this now 6 year old tutorial

matthewhsingleton.com/coding-with-a-rubber-ducky/2016/5/26/… – RubberDucky4444

like image 6
RubberDucky4444 Avatar answered Nov 11 '22 04:11

RubberDucky4444