Как добавить функцию поиска в табличное представление, в котором есть данные API yelp? - PullRequest
0 голосов
/ 24 февраля 2020

Я хочу добавить функцию поиска категории ресторана в RestaurantTableViewController, использующую бизнес-данные yelp api. Я следовал базовой панели поиска c в руководствах по просмотру таблиц, но я не делаю этого для своего конкретного c сценария. Я не различаю отфильтрованные данные и не отфильтрованные данные в моем RestaurantTableViewController, когда поиск активен.

RestaurantTableViewController ниже:

import UIKit
import CoreLocation

protocol ListActions: class {
    func didTapCell(_ viewController: UIViewController, viewModel: RestaurantListViewModel)
}

class RestaurantTableViewController: UIViewController, UITableViewDelegate, FiltersViewControllerDelegate {

    @IBOutlet weak var yourLocationLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var searchBar: UISearchBar!

    private let locationManager = CLLocationManager()
    private let locationService = LocationService()

    var filteredData: [RestaurantListViewModel]!

    let appDelegate = UIApplication.shared.delegate as? AppDelegate

    var viewModels = [RestaurantListViewModel]() {

        didSet {
            DispatchQueue.main.async {
                // this no more loading, i notice it load late that is why when reload data in table view not working
            }
        }
    }

    weak var delegate: ListActions?

    override func viewDidLoad() {
        super.viewDidLoad()

        filteredData = appDelegate!.data

        userCurrentLocation()
        DispatchQueue.main.async {
            self.tabBarController?.tabBar.isHidden = false
        }
        if appDelegate?.data?.count == 0 {
            tableView.setEmptyView(title: "There are no restaurants in your current location.", message: "Please change your location and try again!")
        }
        tableView.reloadData()
    }
    override func viewWillAppear(_ animated: Bool) {
        if appDelegate?.data?.count == 0 {
            tableView.setEmptyView(title: "There are no restaurants in your current location.", message: "Please change your location and try again!")
        }
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("did appear")
        self.removeActivityIndicator()
        tableView.reloadData()
        tableView.dataSource = self
        tableView.delegate = self
        DispatchQueue.main.async {
            self.tabBarController?.tabBar.isHidden = false
        }
    }
    }

extension RestaurantTableViewController: UITableViewDataSource {
    // MARK: - Table view data source
    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
        return "RestaurantCell"
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("number of rows \(String(describing: viewModels.count))")
        print(viewModels)

        if appDelegate?.data?.count == 0 {
            self.tableView.setEmptyView(title: "There are no restaurants in your current location.", message: "Please change your location and try again!")
        }

        if (self.searchBar.isUserInteractionEnabled) {
            return self.filteredData.count
        }
        else {
            return appDelegate!.data?.count ?? 0
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "RestaurantCell", for: indexPath) as! RestaurantTableViewCell
        if (self.searchBar.isUserInteractionEnabled) {
            let vm = filteredData?[indexPath.row]
            cell.configure(with: vm!)
            return cell
        } else {
            let vm = appDelegate!.data?[indexPath.row]
            cell.configure(with: vm!)
            return cell
        }
    }

    // MARK: - Delegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let detailsViewController = storyboard?.instantiateViewController(withIdentifier: "DetailsViewController")
            else {return}
        navigationController?.pushViewController(detailsViewController, animated: true)
        let vm = appDelegate!.data?[indexPath.row]
        appDelegate!.didTapCell(detailsViewController, viewModel: vm!)

        if let selectedRowIndexPath = self.tableView.indexPathForSelectedRow {
            self.tableView.deselectRow(at: selectedRowIndexPath, animated: true)
        }
    }
}

extension RestaurantTableViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    filteredData = searchText.isEmpty ? appDelegate?.data : appDelegate?.data?.filter { (item: RestaurantListViewModel) -> Bool in
            return item.categories[0].title.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
    }
    tableView.reloadData()
    }
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        self.searchBar.showsCancelButton = true
    }
}

Мои RestaurantTableViewCell данные ниже и Я получаю данные ячейки таблицы ресторана в функции configure. Но в методе RestaurantTableViewController cellForRow я не отличаюсь отфильтрованными и обычными данными при активном поиске.

class RestaurantTableViewCell: UITableViewCell {

    @IBOutlet weak var cardContainerView: ShadowView!
    @IBOutlet weak var restaurantImageView: UIImageView!
    @IBOutlet weak var makerImageView: UIImageView!
    @IBOutlet weak var restaurantNameLabel: UILabel!
    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var restaurantType: UILabel!

    let cornerRadius : CGFloat = 10.0

    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
        cardContainerView.layer.cornerRadius = cornerRadius
        func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        cardContainerView.layer.shadowColor = UIColor.gray.cgColor
        cardContainerView.layer.shadowOffset = CGSize(width: 5.0, height: 5.0)
        cardContainerView.layer.shadowRadius = 15.0
        cardContainerView.layer.shadowOpacity = 0.9

        restaurantImageView.layer.cornerRadius = cornerRadius
        restaurantImageView.clipsToBounds = true
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

    }

    func configure(with viewModel: RestaurantListViewModel) {
        // For background thread
        DispatchQueue.global(qos: .background).async {
            DispatchQueue.main.async {
                self.restaurantImageView.af_setImage(withURL: viewModel.imageUrl)
                self.restaurantNameLabel.text = viewModel.name
                self.locationLabel.text = "\(viewModel.formattedDistance) m"
            }
        }
        if let restaurantType: String = String(viewModel.categories[0].title) {
            self.restaurantType.text = restaurantType
        }
    }
}

RestaurantListViewModel также ниже:

struct Business: Codable {
    let id: String
    let name: String
    let imageUrl: URL
    let distance: Double
    let categories: [Category]
}

struct RestaurantListViewModel {
    let name: String
    let imageUrl: URL
    let distance: Double
    let id: String
    let categories: [Category]
}

extension RestaurantListViewModel {
    init(business: Business) {
        self.name = business.name
        self.id = business.id
        self.imageUrl = business.imageUrl
        self.distance = business.distance
        self.categories = business.categories
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...