Ios 让autocomplete在swift中工作
我正在尝试实现自动完成,但找不到在Swift中有效的示例。下面,我尝试转换2010年的示例代码。最后,代码进行了编译,但是包含可能的补全的表没有出现,我也没有经验去理解为什么shouldChangeCharactersInRange没有取消隐藏它Ios 让autocomplete在swift中工作,ios,swift,autocomplete,Ios,Swift,Autocomplete,我正在尝试实现自动完成,但找不到在Swift中有效的示例。下面,我尝试转换2010年的示例代码。最后,代码进行了编译,但是包含可能的补全的表没有出现,我也没有经验去理解为什么shouldChangeCharactersInRange没有取消隐藏它 class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate { @IBOutlet weak var
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
}
}
将
SearchAutoCompleteTentriesWithSubString
函数内容替换为以下内容。我希望它能帮助你
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中设置为self。最后一个问题是表格没有显示自动完成结果,但这也是固定的。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
}
}这里有一种方法可以添加多个标记,它基于像twitter一样键入的“#” 变量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’s解决方案,因此当您选择单元格时,它会在用户已键入的位置后正确地追加该单元格
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
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在autocomplete texfield上工作,@dane提供的代码工作得很好。但你必须改变这一行:
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
借
此外,您可能会注意到,it是区分大小写的,如果默认情况下输入小写字符串(例如cats),它将不起作用。因此,要解决此问题,可以替换为将选项“CaseSensitiveSearch”添加到substringRange声明中(在func SearchAutoCompleteTentriesWithSubString中)。它应该是这样的:
let substringRange :NSRange! = myString.rangeOfString(substring,options [.CaseInsensitiveSearch])
希望它能帮你节省一天 让它在下面工作。大写/小写最初将其丢弃。我用它来自动完成国家名称
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
}
}
我编写了一个教程,里面有很多关于如何重新创建这个已经有6年历史的教程的图片
matthewhsingleton.com/coding-with-a-ruber-ducky/2016/5/26/…-添加了RubberDucky4444表视图,但没有故事板
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中使用google places API,并且需要不区分大小写。这里是更新后的代码,您只需输入:
let subStringRange : NSRange! = myString.range(of: substring, options: .caseInsensitive)
用以下函数替换
cellforrowatinexpath
为了简化这项工作,这里有一个很好的库:Add
view.addSubview(autocompleteTableView)
在
视图中加载。它会起作用。子字符串范围类型是NSRange而不是let,然后必须检查子字符串范围。位置==0,而不是自动完成URL。追加(curString)是-我引入了indexOfPastUrls而不是子字符串范围。位置==0,因为我无法确定如何使子字符串范围类型为NSRange。我已尝试指定let substringRange:NSRange并强制转换方程的另一面。@DrWhat..如何以及何时调用“func textField(textField:UITextField!,shouldChangeCharactersInRange:NSRange,replacementString:string!)->Bool”“method?@dhaval shah-这是一个委托方法,所以我的理解是,在输入字符之前,它会自动被调用。是的,谢谢你的回复!这看起来好多了。因此,在Swift myString.rangeOfString(substring)中,可以使用myString:NSString和substring:String。我不知道你是怎么知道的,但是谢谢你!!!如果我有足够的声誉,我会投票支持这个。不幸的是,我的自动完成表还没有出现,所以我希望你不介意我把问题留着。我最后自己回答了这个问题,所以我认为你做了困难的部分。再次感谢。感谢您提供的简单而精彩的解决方案。。。!它很有魅力。。当tableview有多个分区且每个分区都有多行时,如何实现这一点……?我遇到一个错误:在展开autocompleteTableView!时发现为零!。委派=自我
。您是否使用Interface Builder创建了autocompleteTableView
?如果没有在任何其他位置完成,我会在viewDidLoad中将textField.delegate分配给self。为了其他人的利益,我还要指出,上面的代码假设一个现有的单元原型。如果您想使用默认单元格运行它,我会在CellForRowatineXpath方法中使用以下内容:cell=UITableViewCellStyle(style:UITableViewCellStyle.default,reuseIdentifier:cellIdentifier)dane,感谢这段代码,非常有用。仅供参考,只需使用interface builder添加一个tableview并将其连接到名为autocompleteTableView的IBOutlet就可以轻松得多。根据@LNI注释,我已在interface builder的文本字段下直接添加了一个tableview,并将其连接到名为autocompleteTableView的IBOutlet。这允许我设置原型单元的重用标识符以及tableview本身的自动布局约束。这种方法在Xcode 7.2和Swift 2.1中适用。在Swift 2.1.1中,我必须调整行的语法,使搜索在@edess示例中不区分大小写。新语法如下:let substringRange:NSRange!=myString.rangeOfString(子字符串,选项:.CaseInsensitiveSearch)使用let cell=UITableViewCell(style:UITableViewCellStyle.Default,reuseIdentifier:cellIdentifier)
每次都会创建一个新的单元格,这会降低应用程序的速度并消耗大量内存。最好使用@dane的方法,但使用以下方法在tableView中注册重用标识符:func registerClass(\uCellClass:AnyClass?,forCellReuseIdentifier identifier:String)
大家好,我使用的是搜索API,虽然这在理论上可以回答问题,但要在这里包括答案的基本部分,并提供链接供参考。嗨,欢迎来到Stack Overflow,谢谢你的第一个答案。为了让答案对其他人更有用,最好的做法是让你的答案更详细,例如包括一个显示wh的代码示例
let subStringRange : NSRange! = myString.range(of: substring, options: .caseInsensitive)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
var data = autocompleteUrls[indexPath.row]
cell.textLabel?.text = data as String
return cell
}