I have a SearchBar in my NavigationBar. When the SearchBar is clicked, It should show over the "Back" button on the Navigation bar.
Link to what I want to achieve
So I want to hide the back button like in the image above but I am not achieving that the searchbar overlaps the back button. Can anyone please help
Here is my code:
class FirstSearchTableViewController: UITableViewController, UISearchResultsUpdating {
let searchData = []
var filteredSearchData = [String]()
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.placeholder = "Search for persons"
controller.searchBar.sizeToFit()
controller.searchBar.searchBarStyle = UISearchBarStyle.Minimal
controller.searchBar.setValue("X", forKey: "_cancelButtonText")
(UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self])).tintColor = UIColor.grayColor()
self.navigationItem.titleView = controller.searchBar
controller.hidesNavigationBarDuringPresentation = false
return controller
})()
// Reload the table
self.tableView.reloadData()
self.tableView.backgroundColor = UIColor(red: 14/255.0, green: 23/255.0, blue: 38/255.0, alpha: 1)
self.tableView.separatorColor = UIColor(red: 60/255.0, green: 69/255.0, blue: 83/255.0, alpha: 1)
self.tableView.rowHeight = 80.0
self.navigationController?.navigationBar.topItem?.title = ""
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// 1
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 2
if (self.resultSearchController.active) {
return self.filteredSearchData.count
}
else {
return self.searchData.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
// 3
if (self.resultSearchController.active) {
cell.textLabel?.text = filteredSearchData[indexPath.row]
return cell
}
else {
cell.textLabel?.text = searchData[indexPath.row] as? String
return cell
}
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
filteredSearchData.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (searchData as NSArray).filteredArrayUsingPredicate(searchPredicate)
filteredSearchData = array as! [String]
self.tableView.reloadData()
}
}
i think these delegate might help you:
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
self.navigationItem.setHidesBackButton(true, animated:true);
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
self.navigationItem.setHidesBackButton(false, animated:true);
}
this link answer may give you some pointer see implementation of above methods in link aanswer
Related
My tableview isn't loading once I press build, can anyone see what's wrong with the code as to why it's not showing up? In the console, it's printing the data from Firestore, but I can't see anything on the simulator but a white screen.
struct Posts {
var caption:String
}
class CoursesVC: UIViewController, UITableViewDelegate {
let tableView = UITableView()
var posts = [Posts]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.tableView.dataSource = self
self.tableView.delegate = self
setupViews()
loadPosts()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
func loadPosts() {
let dbUsers = Firestore.firestore().collection("Payouts")
dbUsers.addSnapshotListener { (querySnapshot, error) in
if let error = error {
print("\(error.localizedDescription)")
} else {
for document in (querySnapshot?.documents)! {
if let Caption = document.data()["amount"] as? String {
print(Caption)
var post = Posts(caption: "")
post.caption = Caption
self.posts.append(post)
}
}
DispatchQueue.main.async
{
self.tableView.reloadData()
}
print(self.posts)
}
}
}
private func setupViews() {
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.spacing = 28
sv.axis = .vertical
sv.distribution = .fill
sv.alignment = .fill
return sv
}()
view.addSubview(stackView)
view.addSubview(tableView)
}
}
extension CoursesVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.caption
return cell
}
}
You forgot to assign frame to your tableView. As you are adding your tableView programatically so, you have to set frame for your tableView. Write below code in your setupViews() method.
E.g. tableView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 450.0)
Change tableView frame as per your requirement.
I need to make custom UISearchBar using UITextField.
I try to make it myself, but nothing works. Please, write a code for UITextField, which will work like UISearchBar
It's code where I use UISearchBar, but I need to change to UITextField
class FoodViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
let tableView = UITableView()
var foods = [FoodModel]()
var searchedFoods = [FoodModel]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
fetchFoods()
self.modalPresentationCapturesStatusBarAppearance = true
self.view.backgroundColor = UIColor.white
let controller = UIViewController()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView)
tableView.delegate = self
tableView.dataSource = self
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 5, width: 350, height: 40))
searchBar.searchBarStyle = .minimal
searchBar.barStyle = .black
searchBar.delegate = self
self.view.addSubview(searchBar)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.updateLayout(with: self.view.frame.size)
}
func updateLayout(with size: CGSize) {
self.tableView.frame = CGRect.init(x: 0, y: 45, width: size.width, height: 400)
}
func fetchFoods() {
Database.database().reference().child("food").observe(.childAdded) { (snapshot) in
if let dict = snapshot.value as? [String: AnyObject] {
let newTitle = dict["title"] as! String
let exCell = FoodModel(title: newTitle)
self.foods.append(exCell)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
extension FoodViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if searching {
let food = searchedFoods[indexPath.item]
cell.textLabel?.text = food.title
} else {
let food = foods[indexPath.item]
cell.textLabel?.text = food.title
}
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchedFoods.count
} else {
return foods.count
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var titleOfFood = String()
if searching == true {
titleOfFood = searchedFoods[indexPath.row].title
print(titleOfFood)
} else {
titleOfFood = foods[indexPath.row].title
print(titleOfFood)
}
let alertController = UIAlertController(title: "Hello", message: "Message", preferredStyle: .alert)
let cancel = UIAlertAction(title: "Cancel", style: .default)
let save = UIAlertAction(title: "Save", style: .cancel) { (action) in
self.dismiss(animated: true, completion: nil)
}
alertController.addTextField { (textField) in
textField.keyboardType = .numberPad
textField.borderStyle = .roundedRect
textField.layer.borderColor = UIColor.clear.cgColor
textField.addConstraint(textField.heightAnchor.constraint(equalToConstant: 50))
textField.font = UIFont(name: "Roboto-Medium", size: 30)
// textField.cornerRadius = 8
}
alertController.addAction(save)
alertController.addAction(cancel)
self.present(alertController, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
}
}
extension FoodViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.tableView {
SPStorkController.scrollViewDidScroll(scrollView)
}
}
}
extension FoodViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchedFoods = foods.filter({ $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() })
searching = true
tableView.isHidden = false
tableView.reloadData()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.customHeight = 620
transitionDelegate.showIndicator = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tableView.reloadData()
}
}
Basically (if i'm understanding you correctly) after you add your UITextField to the view, all you need to have is some method to trigger whenever the value of the UITextField changes.
Something like this:
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
And then:
func textFieldDidChange(_ textField: UITextField) {
let searchText = textField.text!
searchedFoods = foods.filter({ $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() })
searching = true
tableView.isHidden = false
tableView.reloadData()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.customHeight = 620
transitionDelegate.showIndicator = false
}
enter image description hereI am having trouble implementing a didSelectRowAtIndexPath from a searchBar filtered tableView cell. When I update the tableView list based on searchbar textDidChange, and perform a show segue to another ViewController, the navigationBar Title is always displaying the non-filtered tableViews indexPath 0. In other words, I would like to have the navigation title display the text from the didSelectAtIndex of search results tableView (not the original indexPath cell text from the non-filtered tableView). Hopefully that makes sense, and thanks in advance!
// viewDidLoad method
override func viewDidLoad() {
super.viewDidLoad()
searchBar.searchBarStyle = UISearchBarStyle.prominent
searchBar.placeholder = " Search Places..."
searchBar.sizeToFit()
searchBar.isTranslucent = false
searchBar.backgroundImage = UIImage()
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
navigationItem.titleView = searchBar
ref = FIRDatabase.database().reference()
fetchPlaces()
placesClient = GMSPlacesClient.shared()
locationManager.requestAlwaysAuthorization()
tableView.allowsMultipleSelectionDuringEditing = true
}
var placeList = [Place]()
var placesDictionary = [String: Place]()
// fetch places for tableView method
func fetchPlaces() {
let uid = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference().child("users").child(uid!).child("Places")
ref.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let place = Place()
place.setValuesForKeys(dictionary)
if let addedBy = place.addedBy {
self.placesDictionary[addedBy] = place
self.placeList.insert(place, at: 0)
}
//this will crash because of background thread, so lets call this on dispatch_async main thread
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
// search variables
lazy var searchBar:UISearchBar = UISearchBar()
var isSearching = false
var filteredData = [Place]()
// searchBar method
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
isSearching = false
view.endEditing(true)
tableView.reloadData()
} else {
isSearching = true
filteredData = placeList.filter({$0.place?.range(of: searchBar.text!) != nil})
tableView.reloadData()
}
}
// tableView methods
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching {
return filteredData.count
}
return placeList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
if isSearching {
cell.textLabel?.text = filteredData[indexPath.row].place
} else {
cell.textLabel?.text = placeList[indexPath.row].place
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let placeDetailsVC = CurrentUserPlaceDetailsVC()
if isSearching == false {
placeDetailsVC.navigationTitle = placeList[(indexPath.row)].place
show(placeDetailsVC, sender: self)
} else {
placeDetailsVC.navigationTitle = filteredData[(indexPath.row)].place
show(placeDetailsVC, sender: self)
}
}
}
Create a string in your up coming ViewController.
class CurrentUserPlaceDetailsVC: UIViewController {
var navigationTitle: String?
override func viewDidLoad(){
super.viewDidLoad()
self.navigationItem.title = navigationTitle
}
}
Now instead of assigning the title directly to navigationBar you should assign it first to that string and then to navigationBar in viewDidLoad method of your viewController.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let placeDetailsVC = CurrentUserPlaceDetailsVC()
// Get Cell Label
placeDetailsVC.navigationTitle = placeList[indexPath.row].place
show(placeDetailsVC, sender: self)
}
I'm making an app that displays data from Firebase , I have a TV that has to show one fixed cell (to choose the type of data to display) and the other cell to display data from server this is the code:
import UIKit
import Firebase
import SwiftDate
class EventiTVC: UITableViewController {
let userID = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference()
let utente = UserDefaults.standard
#IBOutlet weak var Menu_button: UIBarButtonItem!
var Eventi:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
if self.revealViewController() != nil {
Menu_button.target = self.revealViewController()
Menu_button.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
let imageView = UIImageView(image: #imageLiteral(resourceName: "Hangover_Background"))
imageView.contentMode = .scaleAspectFill
self.tableView.backgroundView = imageView
self.tableView.tableFooterView = UIView()
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white,NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: 19)!]
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.revealViewController() != nil {
Menu_button.target = self.revealViewController()
Menu_button.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
self.navigationController?.navigationBar.barTintColor = UIColor.orange
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: 19)!,NSForegroundColorAttributeName : UIColor.white]
DeterminaInfoProprietario()
DeterminoLocali()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if section == 0{
return 1
}
else {
return Eventi.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0{
let cell = Bundle.main.loadNibNamed("Event_Type", owner: self, options: nil)?.first as! Event_Type
return cell
}
else {
let cell = Bundle.main.loadNibNamed("Evento", owner: self, options: nil)?.first as! Evento
let EventoCorrente = Eventi[indexPath.row]
// scarico info Evento corrente ref.child("Eventi").child(EventoCorrente).observeSingleEvent(of: .value, with: { (snap) in
if snap.childrenCount != 0 {
let DatiEvento = snap.value as? NSDictionary
cell.Nome.text = DatiEvento?.value(forKey: "Nome") as! String!
cell.Locale.text = DatiEvento?.value(forKey: "Locale") as! String!
let urlcopertina = DatiEvento?.value(forKey: "Immagine Copertina") as! String!
cell.Copertina.aail_load(url: NSURL(string: urlcopertina!)!)
// per scaricare il colore , devo scaricare il locale
let locale = DatiEvento?.value(forKey: "Locale") as! String!
var Colore:UIColor? = nil
var Ombra:UIColor? = nil
self.ref.child("Locali").child(locale!).observeSingleEvent(of: .value, with: { (snap2) in
if snap2.childrenCount != 0 {
let DatiLocale = snap2.value as? NSDictionary
Colore = ColoriDaStringa(Colore: (DatiLocale?.value(forKey: "Colore Pagina"))! as! String)[0]
Ombra = ColoriDaStringa(Colore: (DatiLocale?.value(forKey: "Colore Pagina"))! as! String)[1]
cell.ViewC.backgroundColor = Colore!
cell.View_ombra.backgroundColor = Ombra!
}
})
}
else {
// Evento Cancellato? // gestire situazione
}
})
return cell
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
if indexPath.row == 0{
return 44
}else {
return 190
}
}
#IBAction func ritornaHome (Segue:UIStoryboardSegue){
}
}
I got 2 static cell and 1 dynamic cell, it should be the other way around, any idea why?
In your cellForRowAtIndexPath() method you should change your if statement from:
if (indexPath.row == 0)
to
if (indexPath.section == 0)
Modify these two functions to:
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Eventi.count+1
}
As we should go with latest features. You should go with Auto layout. Auto layout has in built feature for showing dynamic height of UITableView Cell. Refer below link if you want to learn.
Dynamic cell height UITableview
Otherwise here we have answer of issue in your code.
In numberOfSections() you have set wrong condition. Just replace
return 2
to
return 1
And
in numberOfRowsInSection() replace
if section == 0{
return 1
}
else {
return Eventi.count
}
to
return Eventi.count+1
So I have a textField, which when the user presses, it shows a UIPickerView, which is populated from an array.
Is it possible for there to be search bar at the top of the pickerView, so the user can search for something in the pickerView?
I've not seen this done before so have no idea if it's possible?
Thanks in advance.
UIPickerView is really meant for a few options - if you need to present something that has a lot more options, I would suggest a table view with a search bar. Search Bar Tutorial is a good start.
Here is an easy solution which I have used on my recent project. First of all you need to concentrate on the following points.
Try to use UITextfield for better customization
Use table view to populate data easily inside your main viewController class.
Avoid using segue thing which is little bit annoying and old fashioned.
Try to make your code more realistic and hassle-free.
First things first :-
I am using Xcode 7.2.2 with Swift 2.1
Using native filter method to filter form the array and reuse that.
Using Array of Array type Dictionary(Swift)
Concentrating on the above points.. :)
Here is my class file. Go through the code and you will understand...
import UIKit
class ComposeMessageClass: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
var filtered = [[String : String]]()
let customerNameForSearch: [[String : String]] = [["name": "Tuhin"], ["name": "Superman"], ["name" : "Rahul"], ["name": "Batman"], ["name": "Spiderman"]]
let customerNameToSearchTemp = ["Tuhin", "Superman", "Rahul", "Batman", "Spiderman"]
var searchActive: Bool = false
#IBOutlet weak var autofillTable: UITableView!
#IBOutlet weak var autofillTableView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.autofillTableView.hidden = true
self.autofillTable.delegate = self
self.autofillTable.dataSource = self
self.autofillTable.backgroundColor = tableViewBackGroundColor
self.autofillTable.separatorColor = tableViewSeperatorColor
self.autofillTable.layer.borderColor = tableViewBorderColor
}
}
override func viewWillAppear(animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
}
func textFieldDidBeginEditing(textField: UITextField) {
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
var updatedTextString : NSString = textField.text! as NSString
updatedTextString = updatedTextString.stringByReplacingCharactersInRange(range, withString: string)
self.filtered.removeAll()
self.customerNameToSearchTemp.filter({ (text) -> Bool in
let tmp: NSString = text
let range = tmp.rangeOfString(updatedTextString as String, options: NSStringCompareOptions.CaseInsensitiveSearch)
if range.location != NSNotFound{
let dataArr = ["name": tmp as String]
filtered.append(dataArr)
}
return false
}
})
if(filtered.count == 0){
filtered = [["name" : "No results found"]]
searchActive = true
} else {
searchActive = true;
}
self.autofillTable.reloadData()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return self.filtered.count
}
return self.customerNameForSearch.count
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.autofillTable.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.backgroundColor = UIColor.clearColor()
cell.textLabel!.textColor = tableViewCellTextColorGreen
cell.textLabel!.textAlignment = .Center
cell.selectionStyle = .None
cell.textLabel!.font = UIFont(name: "System", size:17)
if(searchActive){
if filtered[indexPath.row]["name"]! == "No results found"{
cell.textLabel!.text = self.filtered[indexPath.row]["name"]!
cell.userInteractionEnabled = false
}else{
cell.userInteractionEnabled = true
cell.textLabel?.text = self.filtered[indexPath.row]["name"]!
}
} else {
cell.userInteractionEnabled = true
cell.textLabel?.text = self.appDelegateObjForThisClass.customerNameForSearch[indexPath.row]["name"]!
}
return cell
}
internal func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if(self.autofillTable.respondsToSelector(Selector("setSeparatorInset:"))){
self.autofillTable.separatorInset = UIEdgeInsetsZero
}
if(self.autofillTable.respondsToSelector(Selector("setLayoutMargins:"))){
self.autofillTable.layoutMargins = UIEdgeInsetsZero
}
if(cell.respondsToSelector(Selector("setLayoutMargins:"))){
cell.layoutMargins = UIEdgeInsetsZero
}
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell?.backgroundColor = UIColor.clearColor()
cell?.textLabel?.textColor = tableViewCellTextColorGreen
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell?.backgroundColor = UIColor.blackColor()
cell?.textLabel?.textColor = tableViewCellTextColorWhite
self.selectedCustomerId.removeAll()
if(searchActive){
self.contactNameTxtFld.text = self.filtered[indexPath.row]["name]!
}else{
self.contactNameTxtFld.text = self.appDelegateObjForThisClass.customerNameForSearch[indexPath.row]["name"]!
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?){
self.view.endEditing(true)
}
}
Example to set over the storyboard.
Thanks.
Hope this helped.
Any Modification or suggestion our questions would be appreciated.
I added a custom header view for the table with a textField insted of searcontroller(searchbar) and cancel button programmatically with little custmization to the tableView.
I added the following code to filter and get the updated search results
class ViewController: UIViewController,UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource{
let speciality=["Andhra","Bhihar","uttharPradesh","kerala","karnataka","kashmir","thamilnadu","assam","jarkhand","dolapure","manjil","udaypoor","sholapoor","Atthapure","Barampure","Khasi"]
var filteredArray = [String]()
var shouldShowSearchResults = false
var tableView:UITableView!
var yaxis:CGFloat=10
var txtdateOfOperation:UITextField!
var searchTextField:UITextField!
var cancelButton:UIButton!
override func viewDidLoad() {
let dateOfOperationLabel=UILabel(frame:CGRectMake(8,100,200,16))
dateOfOperationLabel.text="State"
dateOfOperationLabel.textColor=UIColor.blackColor()
dateOfOperationLabel.textAlignment=NSTextAlignment.Left
dateOfOperationLabel.font = UIFont.systemFontOfSize(13.0)
dateOfOperationLabel.numberOfLines = 0;
self.view.addSubview(dateOfOperationLabel)
txtdateOfOperation=UITextField(frame: CGRectMake(8,130,300,28))
txtdateOfOperation.borderStyle=UITextBorderStyle.RoundedRect
txtdateOfOperation.returnKeyType=UIReturnKeyType.Done
txtdateOfOperation.userInteractionEnabled=true
txtdateOfOperation.keyboardType=UIKeyboardType.NumberPad
self.view.addSubview(txtdateOfOperation)
tableView=UITableView(frame: UIScreen.mainScreen().bounds, style: UITableViewStyle.Plain)
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate=self
tableView.dataSource=self
tableView.reloadData()
let view=UIView(frame:CGRectMake(0,0,UIScreen.mainScreen().bounds.width,35))
view.backgroundColor=UIColor.lightGrayColor()
searchTextField=UITextField(frame:CGRectMake(8,3,view.bounds.width-70,28))
searchTextField.borderStyle=UITextBorderStyle.RoundedRect
searchTextField.returnKeyType=UIReturnKeyType.Done
searchTextField.userInteractionEnabled=true
searchTextField.delegate=self
searchTextField.placeholder="Search Here..."
searchTextField.clearButtonMode = .WhileEditing
searchTextField.leftViewMode = UITextFieldViewMode.Always
searchTextField.leftView = UIImageView(image: UIImage(named: "search-icon"))
searchTextField.addTarget(self, action: #selector(searchTextFieldDidBeginEdit), forControlEvents: UIControlEvents.EditingChanged)
view.addSubview(searchTextField)
cancelButton=UIButton(frame:CGRectMake(view.bounds.width-65,3,70,28))
cancelButton.setTitle("Cancel", forState: UIControlState.Normal)
cancelButton.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)
cancelButton.addTarget(self, action: #selector(searchBarCancelButton_Click), forControlEvents: UIControlEvents.TouchUpInside)
cancelButton.userInteractionEnabled=false
view.addSubview(cancelButton)
tableView.tableHeaderView = view
txtdateOfOperation.inputView=tableView
searchTextField.inputView=tableView
self.tableView.reloadData()
}
func textFieldDidBeginEditing(textField: UITextField) {
shouldShowSearchResults = true
cancelButton.userInteractionEnabled=true
cancelButton.setTitleColor(UIColor(red: 51/255, green: 153/255, blue: 255/255, alpha: 1.0), forState: UIControlState.Normal)
tableView.reloadData()
}
func textFieldDidEndEditing(textField: UITextField) {
cancelButton.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)
}
func searchTextFieldDidBeginEdit(textField:UITextField) {
if let searchText=textField.text{
filteredArray = speciality.filter({ (country) -> Bool in
let countryText: NSString = country
return (countryText.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch).location) != NSNotFound
})
tableView.reloadData()
}
}
func searchBarCancelButton_Click(){
searchTextField.text=nil
searchTextField.resignFirstResponder()
shouldShowSearchResults = false
tableView.reloadData()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if shouldShowSearchResults {
return filteredArray.count
}
else {
return speciality.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
if shouldShowSearchResults {
cell.textLabel?.text = filteredArray[indexPath.row]
}
else {
cell.textLabel?.text = speciality[indexPath.row]
}
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 60.0
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if shouldShowSearchResults{
txtdateOfOperation.text=filteredArray[indexPath.row]
searchTextField.text=nil
searchTextField.resignFirstResponder()
txtdateOfOperation.resignFirstResponder()
shouldShowSearchResults=false
filteredArray=[String]()
tableView.reloadData()
}
else{
txtdateOfOperation.text=speciality[indexPath.row]
searchTextField.resignFirstResponder()
tableView.resignFirstResponder()
txtdateOfOperation.resignFirstResponder()
}
}
}
i tested it and its working perfectly