【问题标题】:NSFetchedResultsController and Searching - Return multiple and single sections?NSFetchedResultsController 和搜索 - 返回多个和单个部分?
【发布时间】:2020-09-02 01:58:57
【问题描述】:

编辑:

感谢 pbasdf 帮助我解决这个问题。

固定代码:

   lazy var fetchedResultsController = self.getFetchedResultsController()
    var sectionKeyPath: String? = #keyPath(Object.sectionKey)
    var searchPredicate: NSCompoundPredicate?
   
    // MARK: - Return FRC:
    private func getFetchedResultsController() -> NSFetchedResultsController<Object> { // var fetchedResultsController:
        print("Lazy: getFetchedResultsController()")
        let fetchRequest: NSFetchRequest<Object> = Object.fetchRequest()
        fetchRequest.predicate = searchPredicate
        
        let sortByKey = NSSortDescriptor(key: #keyPath(Object.sectionKey), ascending: true)
        let sortByName = NSSortDescriptor(key: #keyPath(Object.name), ascending: true)
        
        fetchRequest.sortDescriptors = [sortByKey, sortByName]
        fetchRequest.fetchBatchSize = 20
        
        let fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: coreDataStack.managedContext,
            sectionNameKeyPath: sectionKeyPath ?? nil,
            cacheName: nil)
        
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }
    
    private func refreshFRC() {
        fetchedResultsController = getFetchedResultsController() // Reset FRC
        do {  // Load Data:
            try fetchedResultsController.performFetch()
        } catch let error as NSError {
            print("Fetching error: \(error), \(error.userInfo)")
        }
    }

这为您提供了带有可选谓词和 sectionNameKeyPath 的 FRC。然后您可以根据需要进行设置,然后使用 refreshFRC() 设置更改。


我正在使用 NSFetchedResultsController 向 tableview 添加搜索。 我的目标:

  • 根据对象的首字母返回多个部分
  • 搜索时将所有对象归为一个部分。

我有工作代码。而且我可以根据我的 sectionKey 使表格同时执行这两项操作,我只是不知道如何在同一个版本中执行这两项操作。

这是正常行为吗?我正在尝试通过更改 FRC 的 sectionNameKeyPath 和 sortDescriptors 来做一些不可能的事情?还是我只是错过了什么?

private func getFetchedResultsController() -> NSFetchedResultsController<Object> {
        let fetchRequest: NSFetchRequest<Object> = Object.fetchRequest()
        
        let sortByKey = NSSortDescriptor(key: #keyPath(Object.sectionKey), ascending: true)
        let sortByName = NSSortDescriptor(key: #keyPath(Object.name), ascending: true)
        
        switch sectionKeyPath {
        case nil:
            fetchRequest.sortDescriptors = nil
            fetchRequest.fetchBatchSize = 20
        default:
            fetchRequest.sortDescriptors = [sortByKey, sortByName]
            fetchRequest.fetchBatchSize = 20
        }
        fetchRequest.sortDescriptors = [sortByKey, sortByName]
        fetchRequest.fetchBatchSize = 20
        
        let fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: coreDataStack.managedContext,
            sectionNameKeyPath: sectionKeyPath ?? nil,
            cacheName: nil)
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }

我也很好奇为整个 viewController 使用单个 FRC 是否更好,或者为整个对象列表创建一个 FRC 是否更好,并且仅在搜索处于活动状态时使用第二个 FRC?


func updateSearchResults(for searchController: UISearchController) {
    let searchBar = searchController.searchBar
    searchBar.barStyle = .default
    
    switch searchBar.text?.count {
    case nil:
        searchPredicate = nil
        sectionKeyPath = #keyPath(Object.sectionKey)
        tableView.reloadData()
    case 0:
        searchPredicate = nil
        sectionKeyPath = #keyPath(Object.sectionKey)
        tableView.reloadData()
    default:
        sectionKeyPath = nil
        guard let searchText = searchBar.text else { return }
        setSearchPredicate(search: searchText)
    }
    fetchFRC()
    tableView.reloadData()
} // End: updateSearchResults()

func fetchFRC() {
    do {
        try fetchedResultsController.performFetch()
    } catch let error as NSError {
        print("Fetching error: \(error), \(error.userInfo)")
    }
}

【问题讨论】:

  • 你能澄清一下问题吗?你似乎说你可以让它工作,但又说你不能。
  • 你好。我很抱歉。 - 当用户使用搜索栏时,我试图让 FRC 返回一个部分,并根据同一构建中对象的第一个字母返回多个部分。 - 我可以让两者分别发生,这取决于我是否使用 sectionNameKeyPath。 - 我尝试将 sectionNameKeyPath 连接到一个在搜索处于活动状态时会发生变化的变量,但这仍然会在搜索时返回多个部分。 - 搜索功能也很齐全。 - 我的问题是试图弄清楚如何在不搜索时返回多个部分,在搜索时返回单个部分。
  • 你能展示在“正常”(多节)模式和“搜索”模式之间切换的代码吗?大概您更改了 sectionKeyPath ,然后在您的问题中重新调用getFetchedResultsController 代码?
  • 我认为您需要在该updateSearchResults 代码中的fetchFRC 之前重新调用getFetchedResultsController
  • 您的视图控制器中必须有一个 FRC 作为变量:您需要将 getFetchedResultsController 调用的结果分配给该变量。

标签: swift core-data nsfetchedresultscontroller uisearchcontroller


【解决方案1】:

根据 cmets:

  1. 您需要在fetchFRC 之前在updateSearchResults 代码中重新调用getFetchedResultsController;和
  2. 您需要将结果分配给视图控制器中定义的fetchedResultsController var。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多