让自动完成工作在swift中

时间:2014-11-12 11:05:52

标签: ios swift autocomplete

我正在尝试实现自动完成功能,但无法找到适用于Swift的示例。下面,我要转换Ray Wenderlich's autocompletion tutorial和2010年的示例代码。最后,代码会编译,但包含可能的完成的表格不会显示,而且我没有经验可以看到原因它不会被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        
}
}

12 个答案:

答案 0 :(得分:12)

将您的searchAutocompleteEntriesWithSubstring功能内容替换为以下内容。我希望它会对你有所帮助。

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()
}

答案 1 :(得分:8)

该表未出现,因为UITextField委托在viewDidLoad中不是自我。表中还有另一个最终问题没有显示自动完成结果,但这也是固定的。 Ray Wenderlich的基本Objective-C自动完成教程转换为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
}

}

答案 2 :(得分:6)

我整理了一个教程,里面有关于如何重新创建这个现在已有6年历史的教程的图片

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

答案 3 :(得分:4)

适用于iOS 9.0和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        
}
}

答案 4 :(得分:4)

对于未来的人来说,可能会使用Swift 2在自动完成texfield上工作,@ dane提供的代码效果很好。但你必须改变这一行:

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

通过

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

另外,您可能会注意到它区分大小写,如果您默认输入小写字符串(例如cats),则不起作用。因此,要解决此问题,可以替换将选项“CaseSensitiveSearch”添加到substringRange声明(在func searchAutocompleteEntriesWithSubstring中)。它应该看起来像:

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

希望它能帮助你节省一天!

答案 5 :(得分:2)

这是一种基于"#"添加多个标签的方法。像twitter一样输入。

Variable typedSubstring是全局子字符串。

  func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {

autocompleteTableView!.hidden = false
var changedText = (self.textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
var items = changedText.componentsSeparatedByString("#")

if (items.count > 0) {
  typedSubstring  = "#" + items.lastObject as NSString

  self.searchAutocompleteEntriesWithSubstring(typedSubstring)
}

return true

}

改进了DrWhat的解决方案,以便在您选择单元格时,它会在用户输入的位置后正确附加。

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!

let selectedText = selectedCell.textLabel?.text as String!

// Remove what has been typed already
let trimmedString = selectedText.stringByReplacingOccurrencesOfString(typedSubstring, withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)

var currentTextField = textField.text

// then append to what has been typed
textField.text = currentTextField + trimmedString

答案 6 :(得分:2)

让它与下面的工作。上/下案例最初将其抛弃。我用它来自动填写国家/地区名称......

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
    }

}

答案 7 :(得分:2)

添加了没有故事板的表格视图

class ViewController: UIViewController  , UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {


@IBOutlet weak var textField: UITextField!

var autocompleteTableView: UITableView!
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children","aaaaaaaaa","aaaaaaaaaaaaaaaaaaa","aaaaaaaaa","a","aa","aaa"]
var autocompleteUrls = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    autocompleteTableView = UITableView(frame: CGRectMake(self.textField.bounds.minX,self.textField.bounds.maxY,self.textField.bounds.width,self.textField.bounds.height * 4), style: UITableViewStyle.Plain)

    textField.delegate = self

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

    autocompleteTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
    self.view.addSubview(autocompleteTableView)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
    autocompleteTableView.hidden = false
    var substring = (self.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
    {
        var myString:NSString! = curString as NSString

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

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

    autocompleteTableView.reloadData()
    //autocompleteTableView.hidden = false
}

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

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

            let autoCompleteRowIdentifier = "cell"
            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 = self.autocompleteUrls[indexPath.row]

    self.autocompleteTableView.hidden = true
}











 }

答案 8 :(得分:1)

这篇文章对我表示感谢,以防万一你们在swift 3中使用谷歌地方API,你需要不区分大小写的是你必须提供的更新代码:

let subStringRange : NSRange! = myString.range(of: substring, options: .caseInsensitive)

答案 9 :(得分:1)

用以下功能替换cellForRowAtIndexPath

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

    var cell = UITableViewCell()
    var data = autocompleteUrls[indexPath.row]
    cell.textLabel?.text = data as String
    return cell
}

答案 10 :(得分:0)

这里有一个很棒的库,以简化这项工作:https://github.com/apasccon/SearchTextField

答案 11 :(得分:0)

添加view.addSubview(autocompleteTableView)viewdidload中。它会起作用。