TableView Swift with dynamic and fixed cells - swift

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

Related

Swift - Firebase : How to search with multi data? [duplicate]

This question already has answers here:
Query based on multiple where clauses in Firebase
(8 answers)
Closed 2 years ago.
I want to know how to search for multi-entry in Firebase.
Now I only can search with one entry(activity name).
The Activity table and i marked * for which i need add to search entry:
Activity{
* act_id
* act_name
* act_region
* act_district
* act_subDistrict
* act_fee
* act_type
* act_startTime
* act_endTime
act_status
act_owner
act_intro
}
This is my search controller code. Thank you for your help.
import UIKit
import FirebaseDatabase
class SearchTableViewController: UITableViewController, UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil)
#IBOutlet var searchCenterTableView: UITableView!
var userArray = [NSDictionary?]()
var filteredUsers = [NSDictionary?]()
var databaseRef = Database.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
databaseRef.child("Activity").queryOrdered(byChild: "act_name").observe(.childAdded, with: { (snapshot) in
self.userArray.append(snapshot.value as? NSDictionary)
self.searchCenterTableView.insertRows(at: [IndexPath(row: self.userArray.count-1, section: 0)], with: UITableViewRowAnimation.automatic)
}) { (error) in
print(error.localizedDescription)
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != ""{
return filteredUsers.count
}
return self.userArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let user : NSDictionary?
if searchController.isActive && searchController.searchBar.text != ""{
user = filteredUsers[indexPath.row]
}else{
user = self.userArray[indexPath.row]
}
cell.textLabel?.text = user?["act_name"] as? String
cell.detailTextLabel?.text = user?["act_subDistrict"] as? String
return cell
}
func updateSearchResults(for searchController: UISearchController) {
filterContent(searchText: self.searchController.searchBar.text!)
}
func filterContent(searchText:String){
self.filteredUsers = self.userArray.filter{ user in
let username = user!["act_name"] as? String
return(username?.lowercased().contains(searchText.lowercased()))!
}
tableView.reloadData()
}
}
func filterContent(searchText:String, entries:[String]){
self.filteredUsers = self.userArray.filter{ user in
guard let user = user as? User else { return false }
var array:[Bool] = [Bool]()
for key in entries {
let value = user[key] as? String
let entry = value?.lowercased().contains(searchText.lowercased()) ?? false
array.append(entry)
}
return(array.contains(true))
}
tableView.reloadData()
}

SearchController - I dont want data to show when user has not started typing

]I have built a SearchViewController in my app, that simply searches for users.
Everything works great, except when i go into the viewcontroller it displays every user that is in the firebase database before i even have started searching? I want the tableview to not show results until i have typed at least 2 letters. Anyone know i can implement this?
Here is my code:
class FollowUsersTableViewController: UITableViewController ,UISearchResultsUpdating, UISearchControllerDelegate{
// #IBOutlet var followUsersTableView: UITableView!
func updateSearchResults(for searchController: UISearchController) {
searchController.searchResultsController?.view.isHidden = false
filterContent(searchText: self.searchController.searchBar.text!)
self.tableView.reloadData()
}
private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [NSDictionary?]()
var filteredUsers = [NSDictionary?]()
var loggedInUser: User?
var databaseRef = Database.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
//large title
self.title = "Discover"
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
} else {
// Fallback on earlier versions
}
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
self.searchController.delegate = self;
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
databaseRef.child("profile").queryOrdered(byChild: "username").observe(.childAdded, with: { (snapshot) in
let key = snapshot.key
let snapshot = snapshot.value as? NSDictionary
snapshot?.setValue(key, forKey: "uid")
if(key == self.loggedInUser?.uid) {
print("Same as logged in user, so don't show!")
} else {
self.usersArray.append(snapshot)
//insert the rows
self.tableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
self.tableView.reloadData()
}
}) { (error) in
print(error.localizedDescription)
}
// 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
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if searchController.isActive && searchController.searchBar.text != ""{
return filteredUsers.count
}
return self.usersArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell
let user : NSDictionary?
if searchController.isActive && searchController.searchBar.text != ""{
user = filteredUsers[indexPath.row]
}
else
{
user = self.usersArray[indexPath.row]
}
cell.title?.text = user?["username"] as? String
let url = URL(string: user?["photoURL"] as! String)!
cell.userImage?.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "user_male"), options: .progressiveDownload, completed: nil)
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let arr = self.searchController.isActive ? self.filteredUsers : self.usersArray
self.performSegue(withIdentifier: "user", sender: arr[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let dest = segue.destination as! UserProfileViewController
let obj = sender as![String:Any]
dest.selectedUser = obj
}
func filterContent(searchText:String)
{
if searchText != ""{
self.filteredUsers = self.usersArray.filter{ user in
let username = user!["username"] as? String
return(username?.lowercased().contains(searchText.lowercased()))!
}
}
}
So does anyone have any tips on how i can make this work?
this is the error im getting
In your numberOfRowsInSection you are returning self.usersArray.count. If you don't to display all the results you can simply return 0 and none will appear.
If you want to display searches when at least 2 characters have been entered then use the count property of searchBar.text
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" && searchController.searchBar.text.count >= 2 {
return filteredUsers.count
}
return 0
}
In your original code:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if searchController.isActive && searchController.searchBar.text != ""{
return filteredUsers.count
}
return self.usersArray.count
}
You're returning self.userArray.count so that probably explains why it shows the whole unfiltered array at the start without any text input into your searchbar.
I also noticed that your filterContent(searchText:String) function is not called in your code yet.
But I think the return self.usersArray.count line is okay as the default return value when you don't want to change the resulting table yet since it might look off to users when the table is empty, when there are 1 or 2 letters already typed in.
Also,
in the other part of your code:
self.tableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
I don't think self.tableView.reloadData() is necessary anymore when insertRow is used. 🤔
About your crash/error:
In your code block:
if(key == self.loggedInUser?.uid) {
print("Same as logged in user, so don't show!")
} else {
self.usersArray.append(snapshot)
//insert the rows
self.tableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
self.tableView.reloadData()
}
instead of self.tableView.reloadData()
please try:
if(key == self.loggedInUser?.uid) {
print("Same as logged in user, so don't show!")
} else {
self.usersArray.append(snapshot)
//insert the rows
self.tableView.beginUpdates()
self.tableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
self.tableView.endUpdates()
}
This is to explicitly let the tableviewcontroller know that you're starting to edit/change the content. Please take note that using beginUpdates() is always paired with endUpdates(), and shouldn't be used along side reloadData().

Filter data from TableView

How can I filter a tableView by search bar? I fetch data to the tableView from a Firebase database and my search bar is inside navigationBar.
This is my code:
class TableViewCustomer: UIViewController, UITableViewDelegate, UITableViewDataSource {
var ref:DatabaseReference!
var customerList = [CustomerModel]()
lazy var searchBar: UISearchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: 300, height: 20))
#IBOutlet weak var tableViewCustomer: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.placeholder = "Search"
navigationItem.titleView = searchBar
if let textfield = searchBar.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.gray
if let backgroundview = textfield.subviews.first {
backgroundview.backgroundColor = UIColor.white
backgroundview.layer.cornerRadius = 18
backgroundview.clipsToBounds = true
}
}
tableViewCustomer.delegate = self
tableViewCustomer.dataSource = self
ref = Database.database().reference().child("Customer");
ref.observe(DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
self.customerList.removeAll()
for results in snapshot.children.allObjects as! [DataSnapshot] {
let results = results.value as? [String: AnyObject]
let name = results?["Name and surname"]
let phone = results?["Phone"]
let company = results?["Company name"]
let myCustomer = CustomerModel(name: name as? String, phone: phone as? String, company: company as? String)
self.customerList.append(myCustomer)
}
self.tableViewCustomer.reloadData()
}
})
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
#objc func buttonAction(sender: UIButton!) {
dismiss(animated: true, completion: nil)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return customerList.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableViewCustomer.dequeueReusableCell(withIdentifier: "cellCustomer") as! TableViewCellCustomer
cell.layer.backgroundColor = UIColor.init(white: 1, alpha: 0.7).cgColor
let customer: CustomerModel
customer = customerList[indexPath.row]
cell.nameLabel.text = customer.name
cell.phoneLabel.text = customer.phone
cell.companyLabel.text = customer.company
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "description", sender: self)
}
}
Add your search bar, and an empty array. As you search add the suitable items to the empty array, then remove them from the array. Use the new array to index into your UI.

Search bar filtering wrong data

Disparately asking for your assistance
I am trying to filter Table View using search bar but the data I am getting is not in the correct position,
I tried several times to figure it out but without any chance, the result I am getting is only the first row does not matter which Room Number I am typing
I pasted the code below, your assistance is highly appreciated
final let urlString = "http://ccm-hotels.com/ccmandroid/api/getteams.php"
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
#IBAction func BackToMenu(_ sender: UIBarButtonItem) {
let MainMenu = self.storyboard?.instantiateViewController(withIdentifier: "MainMenu") as! MainMenu
self.navigationController?.pushViewController(MainMenu, animated: true)
}
var openCaseRoomArray: [String] = []
var openCaseNameArray: [String] = []
var openCaseRoomArrayF: [String] = []
var inSearchMode = false
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
searchBar.returnKeyType = UIReturnKeyType.done
openCaseRoomArrayF = openCaseRoomArray
let alertController = UIAlertController(title: nil, message: "Please wait\n\n", preferredStyle: .alert)
let spinnerIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
spinnerIndicator.center = CGPoint(x: 135.0, y: 65.5)
spinnerIndicator.color = UIColor.black
spinnerIndicator.startAnimating()
alertController.view.addSubview(spinnerIndicator)
self.present(alertController, animated: false, completion: nil)
let when = DispatchTime.now() + 5
DispatchQueue.main.asyncAfter(deadline: when){
// your code with delay
alertController.dismiss(animated: true, completion: nil);}
self.downloadJsonWithURL()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func downloadJsonWithURL() {
let url=URL(string:"http://ccm-hotels.com/ccmandroid/api/getteams.php")
do {
let allContactsData = try Data(contentsOf: url!)
let allContacts = try JSONSerialization.jsonObject(with: allContactsData, options: JSONSerialization.ReadingOptions.allowFragments) as! [String : AnyObject]
if let arrJSON = allContacts["CurrentOpenCases"] {
for index in 0...arrJSON.count-1 {
let aObject = arrJSON[index] as! [String : AnyObject]
if let Room = aObject["RoomNumber"] as? String {
openCaseRoomArray.append(Room)
}
if let Name = aObject["GuestName"] as? String {
openCaseNameArray.append(Name)
}
}
}
self.tableView.reloadData()
}
catch {
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if inSearchMode {
return openCaseRoomArrayF.count
}
return openCaseRoomArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
if inSearchMode {
cell.openCaseRoom.text = self.openCaseRoomArrayF[indexPath.row]
cell.openCaseName.text = self.openCaseNameArray[indexPath.row]
}else{
cell.openCaseRoom.text = self.openCaseRoomArray[indexPath.row]
cell.openCaseName.text = self.openCaseNameArray[indexPath.row]
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.dopenCaseRoomString = openCaseRoomArray[indexPath.row]
vc.openCaseNameString = openCaseNameArray[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
inSearchMode = false
view.endEditing(true)
tableView.reloadData()
} else {
inSearchMode = true
openCaseRoomArrayF = openCaseRoomArray.filter({$0 == searchBar.text})
tableView.reloadData()
}
}
}
In your func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell method you are showing name from self.openCaseNameArray while you are updating your search result in self.openCaseRoomArrayF. When you are getting the api response you are assigning room and its corresponding name in your two arrays but when you are searching and updating your search result in self.openCaseRoomArrayF the index get changed. Now openCaseNameArray and openCaseRoomArray are in matched index but openCaseNameArray and openCaseRoomArrayF are not in same matched index. So you will not get the corresponding name in openCaseNameArray if you take room from openCaseRoomArrayF.
Try to make a Class (e.g Room) and store Room class object in a array. Search and show from that array. No need to maintain to array for this.

searchBar filtered tableViewCells didSelectItemAt indexPath display in navigationBar Title

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