Getting autocomplete to work in swift

前端 未结 12 488
清酒与你
清酒与你 2020-12-04 15:55

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 c

相关标签:
12条回答
  • 2020-12-04 16:22

    Fixed for iOS 9.0 and Swift 2:

    import UIKit
    
    class UIAutoCompleteTextField: 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
            let 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)
    
            for curString in pastUrls {
                let myString: NSString! = curString as NSString
    
                let 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"
            let 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
        }
    }
    
    0 讨论(0)
  • 2020-12-04 16:27

    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
    }
    

    }

    0 讨论(0)
  • 2020-12-04 16:27

    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

    0 讨论(0)
  • 2020-12-04 16:33

    For future guys, that might get to work on autocomplete texfield with Swift 2, the code provided by @dane works well. but you have to change this line:

    let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
    

    by

    let cell = UITableViewCell(style: UITableViewCellStyle.Default , reuseIdentifier: cellIdentifier)
    

    Also, you might notice that the it is case sensitive, and doesn't work if you enter lowercase string (e.g cats) by default. So to solve this issue you can replace add the option "CaseSensitiveSearch" to the substringRange declaration (in the func searchAutocompleteEntriesWithSubstring). it should look like:

    let substringRange :NSRange! = myString.rangeOfString(substring,options [.CaseInsensitiveSearch])
    

    Hope it will help you save one day!!!

    0 讨论(0)
  • 2020-12-04 16:33

    Got it working with the below. The upper/lower case threw it off initially. I'm using it to autocomplete country names...

    import UIKit
    
    class billingAddressViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
    
    
        @IBOutlet var countryTextField: UITextField!
        @IBOutlet var countryTableView: UITableView!
    
        var autocompleteCountries = [String]()
    
        // Get list of countries
        let countries = NSLocale.ISOCountryCodes().map { (code:String) -> String in
            let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
            return NSLocale(localeIdentifier: "en_US").displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            countryTextField.delegate = self
    
            countryTableView!.delegate = self
            countryTableView!.dataSource = self
            countryTableView!.scrollEnabled = true
            countryTableView!.hidden = true
        }
    
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
            print("text field has changed")
            countryTableView!.hidden = false
    
            let substring = (self.countryTextField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
            print(substring)
            searchAutocompleteEntriesWithSubstring(substring)
            return true
        }
    
        func searchAutocompleteEntriesWithSubstring(substring: String) {
            autocompleteCountries.removeAll(keepCapacity: false)
            print(substring)
    
            for curString in countries {
                //print(curString)
                let myString: NSString! = curString.lowercaseString as NSString
                let substringRange: NSRange! = myString.rangeOfString(substring.lowercaseString)
                if (substringRange.location == 0) {
                    autocompleteCountries.append(curString)
                }
            }
    
            countryTableView!.reloadData()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return autocompleteCountries.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 = autocompleteCountries[index]
            }
    
            else {
                cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: autoCompleteRowIdentifier)
            }
    
            return cell!
        }
    
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            countryTextField.text = selectedCell.textLabel!.text
            countryTableView.hidden = true
        }
    
    }
    
    0 讨论(0)
  • 2020-12-04 16:35

    Here you have a nice-to-have library in order to simplify that work: https://github.com/apasccon/SearchTextField

    0 讨论(0)
提交回复
热议问题