swift - 在 UICollectionViewController (Swift 4) 中实现 UISearchBarController?

标签 swift uicollectionview uicollectionviewcell uisearchcontroller

我正在尝试在 UICollectionViewController 中实现 UISearchBarController,代码如下:

    class FirstViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchResultsUpdating {

         var titles: [String] = []

         var card: [RecommendArticles]?

         var searchArr = [String](){
            didSet {
               self.collectionView?.reloadData()
        }
    }

        func updateSearchResults(for searchController: UISearchController) {

            guard let searchText = searchController.searchBar.text else {
                return
            }

            searchArr = titles.filter { (title) -> Bool in
                return title.contains(searchText)
            }


        }


        let searchController = UISearchController(searchResultsController: nil)

       override func viewDidLoad() {

        super.viewDidLoad()

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        navigationItem.hidesSearchBarWhenScrolling = true
        self.navigationItem.searchController = searchController
 }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if (searchController.isActive) {
            return searchArr.count
        } else {
             return self.counters
        }

    }

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

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: verticalCellId, for: indexPath) as! VerticalCellId
        if (searchController.isActive) {
            cell.titleLabel.text = searchArr[indexPath.row]
            return cell
        } else {
            if let link = self.card?[indexPath.item]._imageURL {
                let url = URL(string: link)
                cell.photoImageView.kf.setImage(with: url)
            }

            if let title = self.card?[indexPath.item]._title {
                cell.titleLabel.text = title
                titles.append(title)
                print("\(titles)")
            }

            if let source = self.card?[indexPath.item]._source {
                cell.sourceLabel.text = source
            }

            return cell

        }




    }

错误定位如下:

                titles.append(title)
                print("\(titles)")

当我搜索关键字时,过滤的结果不正确,因为 Collection View 单元格会动态变化(我不确定我的表达是否准确)。

但是,如果我像这样设置变量 titles,它会完美地工作:

var titles = ["Tom","Jack","Lily"]

但我必须从互联网上检索 titles 的值。如有任何建议,我们将不胜感激。

下面是在 self.card 之后创建数组的更新题:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        self.view.addSubview(activityView)
        activityView.hidesWhenStopped = true
        activityView.center = self.view.center
        activityView.startAnimating()

        let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
        dynamoDbObjectMapper.load(TheUserIds2018.self, hashKey: "TheUserIds2018", rangeKey: nil, completionHandler: { (objectModel: AWSDynamoDBObjectModel?, error: Error?) -> Void in
            if let error = error {
                print("Amazon DynamoDB Read Error: \(error)")
                return
            }

            DispatchQueue.main.async {
                if let count = objectModel?.dictionaryValue["_articleCounters"] {
                    self.counters = count as! Int
                    self.collectionView?.reloadData()
                    self.updateItems()
                    self.activityView.stopAnimating()
                }

            }

        })

    }



 func updateItems() {
        let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
        var tasksList = Array<AWSTask<AnyObject>>()
        for i in 1...self.counters {
            tasksList.append(dynamoDbObjectMapper.load(RecommendArticles.self, hashKey: "userId" + String(self.counters + 1 - i), rangeKey: nil))
        }
        AWSTask<AnyObject>.init(forCompletionOfAllTasksWithResults: tasksList).continueWith { (task) -> Any? in
            if let cards = task.result as? [RecommendArticles] {
                self.card = cards
                DispatchQueue.main.async {
                if let totalCounts = self.card?.count {
                    for item in 0...totalCounts - 1 {
                        if let title = self.card?[item]._title {
                            self.newTitle = title
                        }
                        self.titles.append(self.newTitle)
                        print("titles: \(self.titles)")
                    }
                }
        }


            } else if let error = task.error {
                print(error.localizedDescription)
            }

            return nil

        }

    }

最佳答案

这不是 UISearchController 的问题。它与您的数据有关。 Collection View 数据源方法-

cellForItemAtIndexPath 仅当单元格出现在 View 中时才起作用。所以你不能在 cellForItemAtIndexPath

中保留创建标题数组的代码

您可以直接过滤 self.card 数组,并使用以下代码在标题中搜索文本,而不是单独将标题字符串保存在数组中进行搜索

self.searchArr = self.card?.filter(NSPredicate(format:"_title CONTAINS[cd] %@",searchText)).sorted(byKeyPath: "_title", ascending: true)

您可以在加载 Collection View 之前创建标题数组 在您创建 self.card

之后的某些地方

关于swift - 在 UICollectionViewController (Swift 4) 中实现 UISearchBarController?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49435046/

相关文章:

ios - 向 UICollectionView 的第一个和最后一个单元格添加填充

swift - 除非滚动,否则 UICollectionViewCells 不会加载

ios - 在 UICollectionView 中隐藏搜索栏

SWIFT 在 24 小时后使单例实例过期

xcode - 如何将 Collection View 数据传递到新的 View Controller

swift - 如何在swift中理解for循环中optionals的模式匹配

ios - UICollectionView 动态单元格内的 YTPlayerView

ios - 根据标题 UITextview 内容更新 UICollectionView 标题高度

ios - Facebook 与 Parse 无法登录 Swift 2.0

ios - 无法打开文件 “***.app”,因为您没有查看它的权限