让自动完成工作在迅速

我试图实现自动完成,但无法find一个在Swift中工作的例子。 下面,我正在转换Ray Wenderlich的自动完成教程和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 } } 

将您的searchAutocompleteEntriesWithSubstring函数内容replace为下面的内容。 我希望这会帮助你。

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

该表没有出现,因为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 } 

}

我整理了一个关于如何重新创build这个6年教程的教程

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

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

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

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

通过

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

此外,您可能会注意到它是区分大小写的,如果您input的是小写string(例如cat),则默认情况下不起作用。 所以要解决这个问题,你可以添加选项“CaseSensitiveSearch”到substringRange声明(在func searchAutocompleteEntriesWithSubstring中)。 它应该看起来像:

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

希望它会帮助你保存一天!

这是一种基于“#”添加多个标签的方法,如twitter所input。

variablestypedSubstring是全局子串。

  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的解决scheme得到了改进,所以当您select一个单元格时,它会在用户input的地方正确添加它。

 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 

得到它与下面的工作。 大写/小写最初把它扔掉了。 我用它来自动填写国名

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

添加没有故事板的表视图

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

这篇文章帮助我感谢,以防万一你们在swift 3中使用谷歌地方API,你需要不区分大小写,这里是你只需要更新的代码:

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

用下面的函数replacecellForRowAtIndexPath

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = UITableViewCell() var data = autocompleteUrls[indexPath.row] cell.textLabel?.text = data as String return cell } 

在这里你有一个很好的图书馆,以简化这项工作: https : //github.com/apasccon/SearchTextField