SearchBar显示错误的活动

时间:2018-03-05 14:14:24

标签: swift uicollectionview filtering uisearchcontroller

我的SearchBar有这个代码来更改我的集合视图:

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

}

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

Search result

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

1 个答案:

答案 0 :(得分:2)

Q.1

  

当我在寻找" A" - 显示错误的结果。我该如何解决这个问题?

A.1

基本上问题的答案非常简单,您只需要查看collectionView(_:cellForItemAt:)实现并替换此行:

let prodInCell = products[indexPath.row]

用这个:

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

为什么?

你的filtered变量中有过滤的数组,所以你需要在搜索过程中从中获取记录;而products数组包含整个时间内原始的项目列表。

Q.2

  

当我点击" X" /取消按钮时 - 我希望显示原始视图。有没有办法在不克隆原始产品数组的情况下实现这一目标?

A.2

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

searchActive = false

为什么?

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

Q.3

  

当我第一次点击搜索按钮时 - 所有产品都会消失。我该如何防止这种情况发生?我希望在搜索字符串为空时显示所有产品。

A.3

在更新updateSearchResults(for:)方法中,您需要检查搜索字词的长度是否为0,如果是,您只需确定filtered = product,如下所示:

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

为什么?

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