Advanced Auto Complete Swift - ios

I have created a simple autocomplete textfield (in which the autocomplete options are displayed in a tableview) through the following code:
import UIKit
class SchoolViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var schoolTextField: UITextField!
#IBOutlet weak var autoCompleteTableView: UITableView!
let schoolPossibilities = ["Redwood", "Fisher", "Bellermen", "Saratoga", "Los Gatos", "Cambell", "Mooreland", "Harker", "Challenger", "Saint Andrews", "Beckens", "Lynbrook", "Menlo", "Gunn", "Aragon", "Kipp"]
var autoCompleteSchools = [String]()
override func viewDidLoad() {
super.viewDidLoad()
autoCompleteTableView.delegate = self
schoolTextField.delegate = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "someCell", for: indexPath)
cell.textLabel?.text = autoCompleteSchools[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autoCompleteSchools.count
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = schoolTextField.text{
let substring = (text as NSString).replacingCharacters(in: range, with: string)
searchAutoCompleteEntries(withSubstring: substring)
}
return true
}
func searchAutoCompleteEntries(withSubstring substring: String){
autoCompleteSchools.removeAll()
for key in schoolPossibilities{
let string = key as NSString
let range = string.range(of: substring)
if range.location == 0{
autoCompleteSchools.append(key)
}
}
autoCompleteTableView.reloadData()
}
}
The problem is that options only show up if what's being typed in the textfield is an EXACT match. How do I change this code so it can tolerate both uppercase and lowercase letters and slight variations?

Use NSCaseInsensitiveSearch as compare option in
outputString.rangeOfString(String, options: NSStringCompareOptions, range: <#T##Range<Index>?#>, locale: <#T##NSLocale?#>)

Related

How to filter array of dictionary data on based on user input in textfield

Hi I using the array model data, I load that data into tableview.
But I want to search that data based on user input in textField.
Code.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let model = array[indexPath.row]
if let rate = model.price
{
cell.pricelbl.text = "$" + rate
}
cell.namelbl.text = model.prodName ?? ""
}
//Textfield delegate methods.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == searchtextfield
{
var foundItems = [BaseApparel]()
foundItems = self.array.filter { $0.prodName == searchtextfield.text! }
self.array = foundItems
self.searchtableview.reloadData()
}
return true
}
Use predicates:
In viewDidLoad(), add the following line
searchtextfield.addTarget(self, action: #selector(valueDidModify(_:)), for: .editingChanged)
Then use this function:
#objc func valueDidModify(_ sender:UITextField){
let predicate = NSPredicate(format:"self.prodName CONTAINS [cd] %#",sender.text)
let filteredArray = self.array.filter{predicate. evaluateWithObject($0)}
}
return numberOfRows as filteredArray.count

UITextfield delegate method in mvvm

I need to search the tableview in mvvm .
my viewmodel:-
function for search:-
func search(searchText :String?) {
filteredListArray = datasourceModel.dataListArray?.filter{($0.restaurantname?.range(of: searchText!, options: .caseInsensitive) != nil)}
}
And in the viewcontroller i just given the textfield delegate method.
my viewcontroller:-
class QM_SearchViewController: UIViewController,UITableViewDelegate,UITableViewDataSource, UISearchBarDelegate,UITextFieldDelegate {
#IBOutlet private weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var txt: UITextField!
var isSearching = false
var search:String=""
var filteredSearchArray = NSMutableArray()
private var searchViewModel :QM_SearchViewModel!
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?, withViewModel viewModel:QM_SearchViewModel) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
searchViewModel = viewModel
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "SEARCH"
txt.delegate = self
searchViewModel.loadData { (isSuccess) in
if(isSuccess == true)
{
self.tableView.reloadData()
}
else{
}
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print("While entering the characters this method gets called")
return true;
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { //delegate method
return false
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchViewModel.numberOfRowsInSection(section: section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "searchcell"
var cell: QM_SearchCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? QM_SearchCell
if cell == nil {
tableView.register(UINib(nibName: "QM_SearchCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? QM_SearchCell
}
cell.setsearchData(search: searchViewModel.datafordisplay(atindex: indexPath))
return cell
}
}
So in the textfield delegate HOW could i search.How could take the search function from viewmodel.How the searching tableview task take place
Just in side your shouldChangeCharactersIn you can call searchViewModel Search Method , if it not trigger update your dataSource Automatically , you will need to trigger your data source after call search Method
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text,
let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange,
with: string)
if updatedText.count > 2 {
let result = searchViewModel.search(searchText :updatedText)
// result Should update your data Source searchViewModel.numberOfRowsInSection , and reload tableView
}
}
return true;
}

Can we use Google's place autocomplete api to populate out tableview cells on swift?

I want to know the process of how we can use google place api so that when we enter a text in a UITextField, the tableview get reloaded to show the autocomplete results. The Documentation given on Google uses its own API. Im new to ios development. Can anyone help me how to proceed? So far i'm done with pod setup etc and i'm able to get text text enter by user in textfield's delegate method.
This is my code, im unable to see any result in my tableview
import UIKit
import GooglePlaces
class ViewController: UIViewController {
#IBOutlet weak var schoolTextField: UITextField!
#IBOutlet weak var schooltableView: UITableView!
var placesClient : GMSPlacesClient?
var resultArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
}
func placeAutocomplete(text:String) {
let filter = GMSAutocompleteFilter()
filter.type = .noFilter
placesClient?.autocompleteQuery(text, bounds: nil, filter: filter, callback: {(results, error) -> Void in //unable to enter in this block
if let error = error {
print("Autocomplete error \(error)")
return
}
if let results = results {
self.resultArray = [String]()
for result in results {
self.resultArray.append(String(describing: result.attributedFullText))
print("Result \(result.attributedFullText) with placeID \(result.placeID)")
}
}
self.schooltableView.reloadData()
})
}
}
extension ViewController:UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText = textField.text ?? ""
placeAutocomplete(text:currentText)
return true
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)as! SchoolCell
cell.schoolLabel.text = resultArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//do something, unable to reach here
}
}
You forgot to instantiate GMSPlacesClient and to call delegate to UITextField and UITableView in viewDidLoad.
override func viewDidLoad() {
super.viewDidLoad()
self.placesClient = GMSPlacesClient()
self.schoolTextField.delegate = self
self.schooltableView.delegate = self
self.schooltableView.dataSource = self
}

cellForRowAtIndexPath method is not called when using autocomplete textfield

I am working on the auto complete textfield in Swift.
I used this example:
Getting autocomplete to work in swift
But for me cellForRowAtIndexPath method is not calling at all. I don't know what mistake I have done here.
My code is like this:
#IBOutlet weak var autocompleteTableView: UITableView!
#IBOutlet weak var searclLocationTextField: UITextField!
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()
override func viewDidLoad() {
super.viewDidLoad()
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
// Do any additional setup after loading the view.
}
// 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 textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
println("banana")
autocompleteTableView.hidden = false
var substring = (searclLocationTextField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
autocompleteTableView.reloadData()
return true
}
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()
}
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)!
searclLocationTextField.text = selectedCell.textLabel!.text
println(searclLocationTextField.text)
}
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()
}
you are getting finally array at this line autocompleteUrls.append(curString) after that you are reloading the tableView, so log the array count below autocompleteUrls.append(curString) this line and if you will get something definitely cellForRowAtIndexPath will be hit.

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
}
}
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()
}
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
}
}
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
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!!!
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
}
}
Here's a way to add multiple tags based on "#" being typed in like twitter.
Variable typedSubstring is the global substring.
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
}
Improved on DrWhat's solution so that when you select a cell, it appends it correctly after where the user has already typed in.
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
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
}
}
table view added without storyboard
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
}
}
This post helped me thanks, just in case you guys are working with google places API in swift 3 and you need case-insensitive here is the updated code you just have to put:
let subStringRange : NSRange! = myString.range(of: substring, options: .caseInsensitive)
Replace cellForRowAtIndexPath with following function
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
var data = autocompleteUrls[indexPath.row]
cell.textLabel?.text = data as String
return cell
}
Here you have a nice-to-have library in order to simplify that work: https://github.com/apasccon/SearchTextField
Add view.addSubview(autocompleteTableView)
in your viewdidload. It will work.

Resources