如何获取集合视图来控制表格视图中的搜索结果?

Posted

技术标签:

【中文标题】如何获取集合视图来控制表格视图中的搜索结果?【英文标题】:How get collection view to controls search results in tableview? 【发布时间】:2019-12-27 21:57:15 【问题描述】:

我一直在尝试通过我的表格视图上方的集合视图来索引我的搜索结果,以便当我在集合视图中按下一个单元格时,它可以索引表格中的结果,如下图所示

到目前为止,代码的工作原理是,一旦我在集合视图中按下一个单元格,它就会将所选类别的文本放在搜索栏中并获得搜索结果,但不久之后模拟器就会崩溃我的错误 Thread 1: Fatal error: Index out of range on cell.configure(withProduct: itemInventory[indexPath.row]) in the cellForRowAt in tableview

提前感谢您的帮助

import UIKit
import Firebase
import FirebaseFirestore

class HomeController: UIViewController 

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var tableView: UITableView!

    var categorys: [Category] = []
    var searchActive : Bool = false

    var itemInventory: [ItemList] = []
    var itemSetup: [ItemList] = []

    override func viewDidLoad() 
        super.viewDidLoad()

        categorys = Category.createCategoryArray()

        searchBar.delegate = self

    
    // fetches Firebase Data
    func fetchProducts(_ completion: @escaping ([ItemList]) -> Void) 
        let ref = Firestore.firestore().collection("products")
        ref.addSnapshotListener  (snapshot, error) in
            guard error == nil, let snapshot = snapshot, !snapshot.isEmpty else 
                return
            
            completion(snapshot.documents.compactMap( ItemList(dictionary: $0.data()) ))
        
    


extension HomeController: UITableViewDelegate, UITableViewDataSource 
    func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        if searchBar.text != "" 
            return self.itemInventory.count
        
        return itemSetup.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell") as ItemCell else  return UITableViewCell() 

        //search not empty
        if searchBar.text != "" 
            cell.configure(withProduct: itemInventory[indexPath.row])
        else
            cell.configure(withProduct: itemSetup[indexPath.row])
        

        return cell
    



extension HomeController: UICollectionViewDelegate, UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return categorys.count
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as! CategoryCell
        let category = categorys[indexPath.row]
        cell.setCategory(category: category)

        return cell
    

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as! CategoryCell
        let category = categorys[indexPath.row]
        cell.setCategory(category: category)
        print("\(category): \(cell.categoryLbl.text!)")

        searchBar.text = cell.categoryLbl.text! //added this so I could get the search results from pressing a cell in the collection view
    



extension HomeController : UISearchBarDelegate, UISearchDisplayDelegate 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
        productInventory = self.itemSetup.filter( (products) -> Bool in
            return products.name.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil ||
                products.category.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil 
        )

        self.tableView.reloadData()

    

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) 
        searchActive = true;
    

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 
        searchActive = false;
        self.searchBar.endEditing(true)
    

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) 
        searchActive = false;
        self.searchBar.endEditing(true)
    

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
        searchActive = false;
        self.searchBar.endEditing(true)
    


class CategoryCell: UICollectionViewCell 

    @IBOutlet weak var categoryLbl: UILabel!
    @IBOutlet weak var categoryView: UIView!

    func setCategory(category: Category) 
        categorylbl.text = category.categoryLabel
    



import UIKit
import SDWebImage
import Firebase

class ItemCell: UITableViewCell 

    weak var product: ProductList!
    weak var infoDelegate: InfoDelegate?
    var addActionHandler: ((Int) -> Void)?

    @IBOutlet weak var productImage: UIImageView!
    @IBOutlet weak var productName: UILabel!
    @IBOutlet weak var categoryLabel: UILabel!

    func configure(withProduct product: ProductList) 
        productName.text = product.name
        categoryLabel.text = product.category
        productImage.sd_setImage(with: URL(string: product.imageUrl))
    

    override func layoutSubviews() 
        super.layoutSubviews()

    


class Category 
    var categoryLabel: String

    init(categoryLabel: String) 

        self.categoryLabel = categoryLabel

    
    class func createCategoryArray() -> [Category] 

        var categorys: [Category] = []

        let category1 = Category(categoryLabel: "All")
        let category2 = Category(categoryLabel: "Veggies")
        let category3 = Category(categoryLabel: "Fruit")
        let category4 = Category(categoryLabel: "Bread")
        let category5 = Category(categoryLabel: "Drinks")
        let category6 = Category(categoryLabel: "Dairy")

        categorys.append(category1)
        categorys.append(category2)
        categorys.append(category3)
        categorys.append(category4)
        categorys.append(category5)
        categorys.append(category6)

        return categorys

    


enum Cats: String 
    case all = ""          //to get all results in search
    case fruit = "Fruit"
    case veggies = "Veggies"
    case bread = "Bread"
    case drinks = "Drinks"
    case dairy = "Dairy"


import Foundation
import UIKit
import Firebase
import FirebaseFirestore

class ItemList 
    var id: String
    var name: String
    var category: String
    var imageUrl: String

    Init(id: String,
         name: String,
         category: String,
         imageUrl: String) 

        self.id = id
        self.name = name
        self.category = category
        self.imageUrl = imageUrl
    

    convenience init(dictionary: [String : Any]) 
        let id = dictionary["id"] as? String ?? ""
        let name = dictionary["name"] as? String ?? ""
        let category =  dictionary["category"] as? String ?? ""
        let imageUrl =  dictionary["imageUrl"] as? String ?? ""


        self.init(id: id,
                  name: name,
                  category: category,
                  imageUrl: imageUrl)
    


【问题讨论】:

【参考方案1】:

这可能是因为您将过滤后的数组设置为productInventory,这在 Cell for row 中没有使用。

【讨论】:

以上是关于如何获取集合视图来控制表格视图中的搜索结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据集合视图中的单元格选择来控制表格视图的内容?

如何使搜索栏不与表格视图一起滚动? [复制]

使用没有搜索栏的获取结果控制器过滤表视图?

使用表格视图快速搜索控制器滚动

表格视图的搜索栏

表格视图单元格中的集合视图