ios - 如何获取 Collection View 来控制表格 View 中的搜索结果?

标签 ios swift uitableview search uicollectionview

我一直在尝试通过表格 View 上方的 Collection View 对搜索结果建立索引,以便当我按下 Collection View 中的单元格时,它可以对表格中的结果建立索引,如下图所示

到目前为止,代码的工作范围是,一旦我在 Collection View 中按下一个单元格,它会将所选类别的文本放置在搜索栏中并获取搜索结果,但不久之后模拟器就会崩溃我在 cell.configure(withProduct: itemInventory[indexPath.row]) 上遇到错误线程 1: fatal error :索引超出范围表格 View 中的 cellForRowAt

提前感谢您的帮助

My View

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

}

最佳答案

这可能是因为您将过滤数组设置为 productInventory,而该数组未在行单元格中使用。

关于ios - 如何获取 Collection View 来控制表格 View 中的搜索结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59506392/

相关文章:

ios - FB 返回且委托(delegate)已释放后取消委托(delegate)调用

IOS用户注册

swift - 如何从 Parse.com 访问自定义用户表列

ios - 如何在启动动画期间更改 iOS 应用程序图标背景颜色?

ios - 带有搜索栏的 UITableView 作为 inputView

ios - -[UITableView dequeueReusableCellWithIdentifier :forIndexPath:] error 断言失败

ios - iCloud:回调 NSFileManager 的 startDownloadingUbiquitousItemAtURL?

iphone - 从响应 NSString 中获取子字符串

swift - 仅使用 shouldSelectItemAt indexPath 函数选择特定单元格

objective-c - 在 tableView 滚动上显示和隐藏导航栏