SearchBar 显示错误 activity

SearchBar displaying wrong activity

我的 SearchBar 有这段代码可以更改我的 collection 视图:

extension ProductsCollectionViewController : UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating
{
    func updateSearchResults(for searchController: UISearchController)
    {
        let searchString = productsSearchController.searchBar.text

        filtered = products.filter({ (item) -> Bool in
            let prodName: NSString = (item as Product).Name() as NSString

            return (prodName.range(of: searchString!, options: NSString.CompareOptions.caseInsensitive).location) != NSNotFound
        })

        ProductsCollection.reloadData()
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar)
    {
        searchActive = true
        ProductsCollection.reloadData()
    }


    func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
    {
        searchActive = false
        ProductsCollection.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar)
    {
        LoadProducts(productsToShow: latestLoadedProducts)
        ProductsCollection.reloadData()
    }

    func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar)
    {
        if !searchActive
        {
            searchActive = true
            ProductsCollection.reloadData()
        }

        productsSearchController.searchBar.resignFirstResponder()
    }
}

extension ProductsCollectionViewController: UICollectionViewDelegate
{

}

extension ProductsCollectionViewController: UICollectionViewDataSource
{

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        if searchActive
        {
            return filtered.count
        }
        else
        {
            return products.count    //return number of rows in section
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "product_collection_cell", for: indexPath) as! ProductsCollectionViewCell

        let prodInCell = products[indexPath.row]
        let imgUrl = prodInCell.GetMainImageURLString()

        if imgUrl == nil || imgUrl == "" // MARK - make sure no "" is used, only nil
        {
            // No main image exists
            cell.ProductImageView.image = UIImage(named: "DefaultProductImage")
        }
        else
        {
            // Main Image exists
            let url = URL(string: imgUrl)
            if let data = try? Data(contentsOf: url!)
            {
                cell.ProductImageView.image = UIImage(data: data)
            }
        }

        // Set fields

        cell.ProductName.text = prodInCell.Name()
        cell.ProductPrice.text = String(prodInCell.Price())
        cell.productUniqueID = prodInCell.UniqueID()
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {
        // Display selected Item
        prodToLoad = products[indexPath.row]
        performSegue(withIdentifier: "view_product_information", sender:self  )
    }

}

我想按名称过滤项目。产品是我用 "name" 作为 属性 制作的自定义 NSObject。当我搜索一个项目时,显示错误的信息:

  1. 当我搜索 "A" 时 - 显示了错误的结果。我该如何解决?
  2. 当我单击 "X"/取消按钮时 - 我希望显示我的原始视图。有没有办法在不克隆原始产品数组的情况下实现这一目标?
  3. 当我第一次点击搜索按钮时 - 所有产品都消失了。我如何防止这种情况发生?我希望在搜索字符串为空时显示所有产品。

Q.1

When I am searching for "A" - wrong results are shown. How do I fix that ?

A.1

基本上这个问题的答案很简单,你只需要看一下 collectionView(_:cellForItemAt:) 实现并替换这一行:

let prodInCell = products[indexPath.row]

有了这个:

let prodInCell = searchActive ? filtered[indexPath.row] : products[indexPath.row]

为什么?

您的 filtered 变量中有 filtered 数组,因此您还需要在搜索过程中从中获取记录;而 products 数组包含完整的原始项目列表。


Q.2

When I click the "X"/Cancel button - I want my original view to be shown. Is there a way to make this happen without cloning the original array of products?

A.2

你。在重新加载数据之前,在 searchBarCancelButtonClicked(_:) 方法中添加类似内容时可以取回原始列表:

searchActive = false

为什么?

在您结束搜索的实现中,当您重新加载所有数据时,当 searchActive 值为 false 时,它​​将从 products 数组加载。


Q.3

When I first click on the search button - all products disappear. How do I prevent this from happening ? I want all products to be shown when search string is empty.

A.3

在更新 updateSearchResults(for:) 方法中,您需要检查搜索词的长度是否为 0,如果是,您只需确保 filtered = product,诸如此类:

filtered = searchString.count = 0 ? products : products.filter({ (item) -> Bool in
    // do whatever you just do already
})

为什么?

因为这使得 filtered 列表最初与所有产品的列表相同。