首页 > 解决方案 > 如何在 UICollection 视图中重新加载部分

问题描述

所以我正在尝试实现一个搜索栏来搜索不同的类别。在网上看了一会儿,我拿了一个 UITableView 的教程,并把它改编成我的 UICollectionView。

搜索工作正常,因为我能够打印进入filteredCategories数组的搜索结果。

我遇到问题的地方是使用新filteredCategories数组重新加载 UICollectionView。我也尝试过collectionView.reloadData()collectionView.reloadSections(NSIndexSet(index: 1) as IndexSet)但没有成功。

似乎在构建该部分时这些值仅传递一次,并且我无法更改它。

这是我的代码:


import UIKit

class ViewController: UIViewController {
    
    var collectionView: UICollectionView!
    
    let categories: [String] = ["Technology", "Science", "Entertainment", "Business", "Health", "Sports"]
    
    var filteredCategories: [String] = ["none"]
    
    var count = 0
    
    var filteredCount = 6
    
    var ready: [String] = ["none"]
    
    var readyCount =  0
    
    func filterIt() {
        if isFiltering {
            ready = filteredCategories
        readyCount = filteredCategories.count
        } else {
            ready = categories
        readyCount = categories.count
        }
        print("second", ready)
    }
    
    lazy var sections: [Section] = [
        TitleSection(title: "NewsStand"),
//        SearchSection(),
        BasicGridSection(categories: ready, count: readyCount)
    ]
    
    
    
    
    lazy var collectionViewLayout: UICollectionViewLayout = {
        var sections = self.sections
        let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
            return sections[sectionIndex].layoutSection()
        }
        return layout
    }()
    
    let searchController = UISearchController(searchResultsController: nil)
    
    var isSearchBarEmpty: Bool {
      return searchController.searchBar.text?.isEmpty ?? true
    }
    
    func filterContentForSearchText(_ searchText: String) {
      filteredCategories = categories.filter { (category: String) -> Bool in
        print("filtered", filteredCategories)
        return category.lowercased().contains(searchText.lowercased())
      }
        filterIt()
      collectionView.reloadData()
        setupCollectionView()
        collectionView.reloadSections(NSIndexSet(index: 1) as IndexSet)
    }
    
    var isFiltering: Bool {
      return searchController.isActive && !isSearchBarEmpty
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Compositional Layout"
        self.view.backgroundColor = UIColor.white
        self.title = "NewsStand"
        setupCollectionView()
        
        filterIt()
        // 1
        searchController.searchResultsUpdater = self
        // 2
        searchController.obscuresBackgroundDuringPresentation = false
        // 3
        searchController.searchBar.placeholder = "Search"
        // 4
        navigationItem.searchController = searchController
        // 5
        definesPresentationContext = true

    }
    
    func setupCollectionView() {
        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: collectionViewLayout)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColor = UIColor.white
        collectionView.register(UINib(nibName: "TitleCell", bundle: .main), forCellWithReuseIdentifier: TitleCell.identifier)
        collectionView.register(UINib(nibName: "GridCell", bundle: .main), forCellWithReuseIdentifier: GridCell.identifier)
        collectionView.register(UINib(nibName: "SearchCell", bundle: .main), forCellWithReuseIdentifier: SearchCell.identifier)
        self.view.addSubview(collectionView)
        collectionView.reloadData()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        collectionView.reloadData()
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        collectionView.reloadData()
    }
    
}

extension ViewController: UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        sections.count
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        sections[section].numberOfItems
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        sections[indexPath.section].configureCell(collectionView: collectionView, indexPath: indexPath)
    }
}

extension ViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let articlesView = storyboard?.instantiateViewController(withIdentifier: "articleViewController") as? ArticleViewController else {
            print("error")
         return
       }
       // set the post id for the comments
       articlesView.set(index: indexPath.item)
//        present(articlesView, animated: true, completion: nil)
        self.navigationController!.pushViewController(articlesView, animated: true)
      }
    
}

extension ViewController: UISearchResultsUpdating {
  func updateSearchResults(for searchController: UISearchController) {
    let searchBar = searchController.searchBar
    filterContentForSearchText(searchBar.text!)
  }
}

和部分:

struct BasicGridSection: Section {

    // TODO: create a constant for the title of the header of type String
    var categories: [String]
    
    var numberOfItems: Int
    
    // TODO: create an initializer to set the title
    init(categories: [String], count: Int) {
        self.categories = categories
        self.numberOfItems = count
    }

    func layoutSection() -> NSCollectionLayoutSection? {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.1), heightDimension: .fractionalHeight(0.8))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.4))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 2)
        let section = NSCollectionLayoutSection(group: group)
        return section
    }

    func configureCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: GridCell.self), for: indexPath) as? GridCell
        cell!.set(label:categories[indexPath.row])
        return cell!
    }
    
}

谢谢!

标签: swiftuitableviewuicollectionview

解决方案


推荐阅读