Search code examples
iosswiftxcodeuisearchbar

Search bar returning only first element from data array


currently I am trying to implement my search bar, but something is wrong and I can't figure it out what it is. Here is the code, and explanation.

//global variable for empty array, its type of Any cause I am getting data from network call
var filteredData: [Any]!
//these are my models, which I am using to display them on screen after mapping in network function
var bookedTrips: [BookedTripsForView]?

func viewDidLoad() {
        super.viewDidLoad()
        filteredData = bookedTrips
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchBar.becomeFirstResponder()
        filteredData = []
        if searchText == "" {
            filteredData = bookedTrips
        }else {
            for trip in (bookedTrips)! {
                if trip.tripName.lowercased().contains(searchText.lowercased()){
                    filteredData.append(trip)
                  //if I type, lets say Barcelona, in console its printed correct result, 
                  //but its displaying only first trip in my array, which is Berlin
                    print("filteredDataArray after appending print: \(String(describing: filteredData))")
                }
            }
        }
        self.tableView.reloadData()
    }

I hope that my explanation is ok, if something's not clear, I will refactor my question. Thanks in advance.

Here is picture of my screen and console

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if let filter = filteredData {
                return filter.count
            } else if let data = bookedTrips {
                return data.count
            }
            return 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
    
    if let trips = bookedTrips?[indexPath.row] {
        cell.configure(trips: trips)
    }
    return cell
}

Solution

  • Short and simple (One line filter)

    var filteredData = [BookedTripsForView]()
    var bookedTrips = [BookedTripsForView]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        bookedTrips = fetchFromAPIorDB()
        filteredData = bookedTrips
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.filteredData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
        cell.configure(trips: filteredData[indexPath.row])
        return cell
    }
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText.isEmpty {
            filteredData = bookedTrips
        }
        else {
            filteredData = bookedTrips.filter({ $0.tripName.lowercased().contains(searchText.lowercased()) })
        }
        self.tableView.reloadData()
    }