I want to search for some data in the table view using the search bar, but when I try to find data in my model, I'm not able to search that data.I made a expand table view cell and created a search bar for searching data, but still I can't search the data in the model. How can I achieve that?
here is my code:
import UIKit
class FAQViewController: UIViewController, UITableViewDataSource {
var dataFaq = [modelFAQ]()
let items = [
modelFAQ(name: "1. search box", description: "The design led users to instinctively search for their question first before clicking the FAQs"),
modelFAQ(name: "2.list of FAQs ", description: "Customers clicked around on the FAQs first."),
modelFAQ(name: "3. customers", description: "top issues first and then use the search for the questions instead of browsing and yielding more relevant results")
]
#IBOutlet fileprivate weak var tableView: UITableView!
#IBOutlet weak var searchDataBar: UISearchBar!
fileprivate var indexPaths: Set<IndexPath> = []
var cellIdentifier = "dataSourceFAQ"
var searchData = [String]()
var searching = false
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
searchDataBar.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchData.count
}else {
return items.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! FAQTableViewCell
if searching{
cell.titleLabel.text = searchData[indexPath.row]
}else{
cell.titleLabel.text = items[indexPath.row].name
}
let nameDetail = self[indexPath].name as? String
let description = self[indexPath].description
cell.update(name: nameDetail ?? "0", description: description)
cell.state = cellIsExpanded(at: indexPath) ? .expanded : .collapsed
return cell
}
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = true
}
private func setupTableView(){
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 200.0
tableView.separatorStyle = .none
}
}
extension FAQViewController: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as!FAQTableViewCell
cell.state = .expanded
self.addExpandedIndexPath(indexPath)
tableView.beginUpdates()
tableView.endUpdates()
print("1")
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! FAQTableViewCell
cell.state = .collapsed
self.removeExpandedIndexPath(indexPath)
tableView.beginUpdates()
tableView.endUpdates()
print("2")
}
}
extension FAQViewController {
func cellIsExpanded(at indexPath: IndexPath) -> Bool {
return indexPaths.contains(indexPath)
}
func addExpandedIndexPath(_ indexPath: IndexPath) {
indexPaths.insert(indexPath)
}
func removeExpandedIndexPath(_ indexPath: IndexPath) {
indexPaths.remove(indexPath)
}
}
extension FAQViewController {
subscript(indexPath: IndexPath) -> modelFAQ {
return items[indexPath.row]
}
}
extension FAQViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchData = searchText.isEmpty ? items: items.filter{ $0.name(searchText)}
searching = true
tableView.reloadData()
}
}
here is my table view cell
import UIKit
class FAQTableViewCell: UITableViewCell {
enum cellState{
case collapsed
case expanded
var carretImage: UIImage {
switch self {
case .collapsed:
return UIImage(named: "ic_arrow_down")!
case .expanded:
return UIImage(named: "ic_arrow_up")!
}
}
}
#IBOutlet private weak var stackView: UIStackView!
#IBOutlet private weak var containerView: UIView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet private weak var carret: UIImageView!
#IBOutlet private weak var descriptionLabel: UILabel!
private let expandedViewIndex: Int = 1
var state: cellState = .expanded {
didSet{
toggle()
}
}
override func awakeFromNib() {
selectionStyle = .none
containerView.layer.cornerRadius = 5.0
}
private func toggle(){
stackView.arrangedSubviews[expandedViewIndex].isHidden = stateIsCollapsed()
carret.image = state.carretImage
}
private func stateIsCollapsed() -> Bool{
return state == .collapsed
}
func update(name: String, description: String){
titleLabel.text = name
descriptionLabel.text = description
}
}
here is my model
struct modelFAQ {
var name: String
var description: String
}
Two issues:
You have to declare searchData as the same type as the main data.
By the way according to the naming convention struct and class names start with a capital letter
var searchData = [ModelFAQ]()
The search filter closure is wrong. Write
searchData = searchText.isEmpty ? items : items.filter{ $0.name.contains(searchText)}
or if you want to search case insensitive
searchData = searchText.isEmpty ? items : items.filter{ $0.name.range(of: searchText, options: .caseInsensitive) != nil }
And you have to change in cellForRowAt
cell.titleLabel.text = searchData[indexPath.row].name
NOTE: Always start class/struct name with CAPITAL LETTER
Wrong: modelFAQ
correct: ModelFAQ
You have made one mistake, you have to declare your searchData Array like below
var searchData = [ModelFAQ]()
and while in datasource method you have to get name from the ModelFAQ object and assign it to your label.
Hope it will help you.
Related
I have a table which has a name and a picture in each cell. I have a search bar which searches through the names which does successfully happen however the images are blank. When you erase your search from the search bar, the images in the cell also do disappear! Would anyone know what I have done wrong and if so can someone please help me out!
Thank you
Had an issue with when search is deleted images are not shown but now it is fixed thanks to Raja
Only issue left is that it does not filter images when searched. Images are still blank when the cells are searched
import UIKit
class TestTableViewController: UITableViewController {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var userWorkoutName: UILabel!
var valueToPass: String!
var workoutName = ["Apple","Orange","Banana"]
var workoutImage = ["A","O","B"]
var searchingWorkouts = [String()]
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
searchingWorkouts = workoutName
}
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 {
if searching {
return searchingWorkouts.count
} else {
return workoutName.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIentifier, for: indexPath) as! WorkoutTableViewCell
if searching {
cell.workoutName.text = searchingWorkouts[indexPath.row]
cell.workoutImage.image = UIImage(named: searchingWorkouts[indexPath.row])
} else {
cell.workoutName.text = workoutName[indexPath.row]
cell.workoutImage.image = UIImage(named: workoutImage[indexPath.row])
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let moreDetail = storyboard.instantiateViewController(identifier: "UploadWorkoutViewController") as! UploadWorkoutViewController
if searching {
moreDetail.getWorkoutTitle = searchingWorkouts[indexPath.row]
} else {
moreDetail.getWorkoutTitle = workoutName[indexPath.row]
}
self.navigationController?.pushViewController(moreDetail, animated: true)
}
}
extension TestTableViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchingWorkouts = workoutName.filter({$0.prefix(searchText.count) == searchText } )
searching = true
if searchText.isEmpty {
searching = false
} else {
searching = true
}
tableView.reloadData()
}
}
Images are blank because you're not filtering the images, you're only filtering the workout names. And while searching you're assigning searchingWorkouts to image, which is totally wrong.
cell.workoutImage.image = UIImage(named: searchingWorkouts[indexPath.row])
Just like maintaining the searchingWorkouts, you need to maintain the searchingWorkoutImage as well. And then change the above line to this
cell.workoutImage.image = UIImage(named: searchingWorkoutImage[indexPath.row])
But the question is how will you filter the image names? Because workout names and image names are different.
So a better solution is to create a Workout class with name and image properties and change your code to the following
class Workout {
var name: String = ""
var image: String = ""
init(name: String, image: String) {
self.name = name
self.image = image
}
}
class TestTableViewController: UITableViewController {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var userWorkoutName: UILabel!
var valueToPass: String!
var workouts = [Workout(name: "Apple", image: "A"), Workout(name: "Orange", image: "O")]
var searchingWorkouts = [Workout]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
searchingWorkouts = workouts
}
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 {
if searching {
return searchingWorkouts.count
} else {
return workouts.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIentifier, for: indexPath) as! WorkoutTableViewCell
if searching {
cell.workoutName.text = searchingWorkouts[indexPath.row].name
cell.workoutImage.image = UIImage(named: searchingWorkouts[indexPath.row].image)
} else {
cell.workoutName.text = workouts[indexPath.row].name
cell.workoutImage.image = UIImage(named: workouts[indexPath.row].image)
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let moreDetail = storyboard.instantiateViewController(identifier: "UploadWorkoutViewController") as! UploadWorkoutViewController
if searching {
moreDetail.getWorkoutTitle = searchingWorkouts[indexPath.row].name
} else {
moreDetail.getWorkoutTitle = workouts[indexPath.row].name
}
self.navigationController?.pushViewController(moreDetail, animated: true)
}
}
extension TestTableViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchingWorkouts = workouts.filter({$0.name.prefix(searchText.count) == searchText } )
searching = true
if searchText.isEmpty {
searching = false
} else {
searching = true
}
tableView.reloadData()
}
}
Im building an app and I have a search bar with table view.
But I don't how when users tap the search, go to the data at different View Controller
Someone can help me pls ?
My code almost like that
#IBOutlet weak var textSearchBar: UITextField!
#IBOutlet weak var tableSearchResult: UITableView!
var fruitsArray:[String] = Array()
var searchedArray:[String] = Array()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
fruitsArray.append("Apple")
fruitsArray.append("Orange")
fruitsArray.append("Litch")
fruitsArray.append("Pineapple")
for str in fruitsArray {
searchedArray.append(str)
}
tableSearchResult.dataSource = self
textSearchBar.delegate = self
}
// Mark:- UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchedArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
cell?.textLabel?.text = searchedArray [indexPath.row]
return cell!
}
// MARK: - UITextFieldDelegate
func textFieldShouldClear(_ textField: UITextField) -> Bool {
textSearchBar.resignFirstResponder()
textSearchBar.text = ""
self.searchedArray.removeAll()
for str in fruitsArray {
searchedArray.append(str)
}
tableSearchResult.reloadData()
return true
}
Thank you Very Much
Try this:
extension ViewController: UISearchBarDelegate {
func searchBar(
_ searchBar: UISearchBar,
textDidChange searchText: String
) {
// Here instructions for when searchBarText change
}
func searchBarCancelButtonClicked(
_ searchBar: UISearchBar
) {
self.searchBar.endEditing(true)
}
}
I am trying to embed the collection view in the table view. When the page gets loaded I will retrieve the data field by field from the database and reloads the data whenever I retrieve the single field from the database. Here while reloading the table view I need to check the value i.e "oneimage" so if that value is not empty it should set to the collection view cell. The problem is whenever I scroll the table view the data in the collection view cells get swapped. Here is the code below
import UIKit
import Firebase
import FirebaseFirestore
import FirebaseAuth
import SDWebImage
struct values {
var quesvalue: String
var answvalue: String
var ImageUrl = [String]()
}
class QuestionsCell: UITableViewCell,UICollectionViewDelegate {
#IBOutlet weak var collectionview: UICollectionView!
#IBOutlet weak var card: UIView!
#IBOutlet weak var question: UILabel!
#IBOutlet weak var answer: UILabel!
#IBOutlet weak var speakbutton: UIButton!
#IBOutlet weak var collectionviewh: NSLayoutConstraint!
var imageArray = [String] ()
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
extension QuestionsCell {
func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource &
UICollectionViewDelegate>(dataSourceDelegate: D, forRow row: Int) {
collectionview.delegate = dataSourceDelegate
collectionview.dataSource = dataSourceDelegate
print("collectionviee.tag",collectionview.tag,row)
collectionview.tag = row
collectionview.contentOffset = .zero // Stops collection view if it was scrolling.
}
}
class CollectionViewCell: UICollectionViewCell{
#IBOutlet weak var backcard: UIView!
#IBOutlet weak var imageview: UIImageView!
var task: URLSessionDataTask?
override func awakeFromNib() {
super.awakeFromNib()
}
override func prepareForReuse(){
imageview.image = nil
}
}
class ViewController: UIViewController ,UITableViewDelegate,
UITableViewDataSource,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var tableview: UITableView!
var JSONArray = [String:Any]()
var quesArray = [String]()
var ansArray = [String]()
var answer : String!
var imagesarray = [String]()
var open : [values] = []
var oneimage = [String]()
var storedOffsets = [Int: CGFloat]()
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
tableview.rowHeight=UITableView.automaticDimension
tableview.estimatedRowHeight=150
Firestore.firestore().collection("User").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Popop").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Answers").document("Earlyyears").getDocument() { (document, error) in
if let document = document, document.exists {
self.open.removeAll()
self.imagesarray.removeAll()
self.oneimage.removeAll()
if let b1 = document.data()!["Name"] as? [String: Any] {
print("1",b1)
if let firstName = b1["Answer"] as? String {
print("firstName is",firstName)
if firstName != "No answer recorded"{
self.answer = firstName
self.ansArray.append(firstName)
if let imageurlarray = b1["ImageURL"] as? [String] {
self.imagesarray = imageurlarray
print("imageurl array in meaning feild is",imageurlarray)
self.open.insert(values(quesvalue: self.quesArray[0],answvalue: self.answer,ImageUrl: self.imagesarray), at: 0)
self.tableview.reloadData()
}
}
}
}
if let b2 = document.data()!["Meaning"] as? [String: Any] {
print("1")
if let firstName = b2["Answer"] as? String {
print("firstName is",firstName)
if firstName != "No answer recorded"{
self.answer = firstName
self.ansArray.append(firstName)
if let imageurlarray = b2["ImageURL"] as? [String] {
self.imagesarray = imageurlarray
print("imageurl array in meaning feild is",imageurlarray)
self.open.insert(values(quesvalue: self.quesArray[1],answvalue: self.answer,ImageUrl: self.imagesarray), at: 1)
self.tableview.reloadData()
}
}
}
}
} else {
print("Document does not exist")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("ansArry.count is",open.count)
return open.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("entered into cellfor row at")
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! QuestionsCell
print("quesrray,ansArray are",quesArray,ansArray,open)
if open.count > indexPath.row{
cell.question.text = open[indexPath.row].quesvalue
cell.answer.text = open[indexPath.row].answvalue
print("cell.ques.text",cell.question.text)
oneimage = open[indexPath.row].ImageUrl
print("onimage before checking",oneimage)
if !oneimage.isEmpty{
print("entered into oneimage not empty",oneimage)
cell.collectionview.isHidden = false
cell.collectionviewh.constant = 160
cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
}
else{
print("dont show collection view")
cell.collectionview.isHidden = true
cell.collectionviewh.constant = 0
}
}
else{
print("<")
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("imagesarray.count is",oneimage.count)
print("oneimage.count")
return oneimage.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: CollectionViewCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as? CollectionViewCell)!
if oneimage.count > indexPath.row{
if oneimage != [""] {
let image = oneimage[indexPath.row]
print("oneimage is",image)
print("entered into oneimage not empty")
cell.imageview.sd_setImage(with: URL(string: image))
}
}
return cell
}
Here are the screenshots of my output.
As I mentioned in the comments, this is because of the reusability. That means when a cell goes out from bottom/top, the same cell (containing the previous setup) comes in from top/bottom. So if you set something async, like a remote image on it, it may be visible on incorrect cell. You should make sure you are selecting correct cell when you are about to set the image on it.
For example you should change this:
cell.imageview.sd_setImage(with: URL(string: image))
to something like this:
(collectionView.cellForItem(at: indexPath) as? CollectionViewCell)?.imageview.sd_setImage(with: URL(string: image))
This will ask the collectionView for the real cell instead of the reused one. I don't know how sd library works, but you may want to do this in the completionHandler of the library.
Maybe this article could help you.
There is table view to show phone contact and a search Bar in view controller . I implemented the code for the search-bar to filter givenName array it works just fine but when I click on the cell that I searched it doesn’t display the right information it displays only the information of the first row( exactly first index). The question it is how i can solve this problem ?
Data Model :
struct ContactStruct {
let identifier : String
let thumbnailImageData : UIImage
let givenName : String
let familyName : String
let phoneNumbers : String
let emailAddresses : String
}
Main View controller :
class NewContactViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var contactsData = [ContactStruct]()
var searchedContact = [String]()
var searching = false
#IBOutlet weak var tblMain: UITableView!
#IBOutlet weak var contactSearchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let story = UIStoryboard(name: "Main", bundle: nil)
let vc = story.instantiateViewController(withIdentifier: "InsertContactViewController") as! InsertContactViewController
vc.strEditFitstName = contactsData[indexPath.row].givenName
vc.stridentifier = contactsData[indexPath.row].identifier
self.navigationController?.pushViewController(vc, animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchedContact.count
} else {
return contactsData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testCell") as! NewContactCell
let contactToDisplay = contactsData[indexPath.row]
contactToDisplay.familyName
cell.lblLName.text = contactToDisplay.givenName
return cell
}
search bar methods:
extension NewContactViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let givenNames = contactsData.map { $0.givenName }
searchedContact = givenNames.filter({$0.lowercased().prefix(searchText.count) == searchText.lowercased()})
searching = true
tblMain.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tblMain.reloadData()
}
}
Follow just below code as an example :
let countriesList = ["African Union",
"Andorra",
"Armenia",
"Austria",
"Bahamas",
"Barbados",
"Belarus",
"Belgium",
]
#IBOutlet var tblPlace: UITableView!
#IBOutlet var searchPlace: UISearchBar!
var selctedCountries:[String] = []
var filteredData: [String]!
override func viewDidLoad() {
super.viewDidLoad()
searchPlace.delegate = self
filteredData = countriesList
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ApplyFilterTableViewCell", for: indexPath) as! ApplyFilterTableViewCell
cell.lblName = filteredData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let story = UIStoryboard(name: "Main", bundle: nil)
let vc = story.instantiateViewController(withIdentifier: "InsertContactViewController") as! InsertContactViewController
vc.strEditFitstName = filteredData[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? countriesList : countriesList.filter({(dataString: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return dataString.range(of: searchText, options: .caseInsensitive) != nil
})
tblPlace.reloadData()
}
I am having a weird issue where for some reason my UITableView is not being reloading after performing a search. The console prints out the correctly filtered data, but the table simply doesn't change. I have never encountered this issue, so I first attempted the solutions which naturally came to mind:
Tried tableView.reloadData() in the Main Queue
Quit Xcode, clean build, reinstall
Cleared out the derived data dir
I have found several similar issue in SO, but all of the solutions I've seen are things I've tried, mainly reloading tableview in main queue.
Hoping maybe I just simply have an issue in my code or something I'm missing.
I am running Xcode 8.3.3
import UIKit
class CategoriesViewController: UIViewController {
var isFiltering = false
var location = Location()
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
var categoriesSearchResults = [Category]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.allowsSelection = true
tableView.keyboardDismissMode = .onDrag
let nib = UINib(nibName: "CategoryTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier:"CategoryTableViewCell");
searchBar.returnKeyType = UIReturnKeyType.done
searchBar.autocapitalizationType = .none
searchBar.delegate = self
}
extension CategoriesViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("HI")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering {
return self.categoriesSearchResults.count
}
return self.location.categories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if let cell = self.tableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as? CategoryTableViewCell {
var category: Category
if isFiltering {
category = self.categoriesSearchResults[indexPath.row]
} else {
category = self.location.categories[indexPath.row]
}
cell.name.text = category.name
cell.status.textColor = UIColor.lightGray
cell.status.text = "Not Verified"
}
return cell
}
}
extension CategoriesViewController : UISearchBarDelegate {
func searchBarIsEmpty() -> Bool{
return self.searchBar.text?.isEmpty ?? true
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.isFiltering = true
self.categoriesSearchResults.removeAll()
tableView.reloadData()
self.view.endEditing(true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBarIsEmpty() {
self.view.endEditing(true)
self.isFiltering = false
} else {
self.isFiltering = true
self.categoriesSearchResults = self.location.categories.filter({ (category: Category) -> Bool in
return category.name.lowercased().contains(searchText.lowercased())
})
}
tableView.reloadData()
}
}
and my custom table view cell:
import UIKit
class CategoryTableViewCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var status: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func prepareForReuse() {
super.prepareForReuse()
self.name.text = ""
self.status.text = ""
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Thank you in advance.
EDIT: Might also be worth mentioning, when I am actively searching, the function tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) is not called??
The scope of if let nests in its scope. In your code you are always returning let cell = UITableViewCell(). Try returning it inside the if let :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if let cell = self.tableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as? CategoryTableViewCell {
var category: Category
if isFiltering {
category = self.categoriesSearchResults[indexPath.row]
} else {
category = self.location.categories[indexPath.row]
}
cell.name.text = category.name
cell.status.textColor = UIColor.lightGray
cell.status.text = "Not Verified"
/// RETURN CELL HERE
return cell
}
return cell
}