【问题标题】:UIApplication's `beginIgnoringInteractionEvents` not workingUIApplication 的 `beginIgnoringInteractionEvents` 不起作用
【发布时间】:2018-05-07 10:44:06
【问题描述】:

首先我为长问题道歉,我个人更喜欢短而精确的问题。

背景

我正在UITableView 中开发搜索功能。存储数据我使用core data。为了显示我使用NSFetchedResultsController 的结果。在我的视图模型中,我有一个单独的 NSFetchedResultsController 来表示搜索结果。

目前我正在使用以下方法

`textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String)` 

UITextFieldDelegate 收听我的UITextField 的变化,并以此为基础开始搜索。

我的perform fetch 部分如下所示

//
// ALL of this operation Run on MainQueue
//
// Preparing NSFetchRequest and setting 
// it's predicate Goes here 
// 

UIApplication.shared.beginIgnoringInteractionEvents()

managedObjectContext?.perform {
        do {
            try self.allContactSearchFetchResultController?.performFetch()
            DispatchQueue.main.async {
                UIApplication.shared.endIgnoringInteractionEvents()
                // calling the delegate which will reload the UITableView
            }

        } catch {
            print("Error occur")
            // TODO 
            // handle error here
        }
    }

我已停止用户交互,因此用户在此搜索结束之前无法再输入键盘。如果启动了多个搜索,tableview 会无限期地重新加载,并且应用程序在访问以下内容时崩溃

managedObject = allContactSearchFetchResultController?.object(at: indexPath)

来自UITableViewDataSource

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

为了一次运行一个搜索操作,我开始忽略用户交互。搜索结束后,我将忽略用户交互。

问题

它工作正常,直到我注意到按下并按住退格按钮,开始忽略用户交互不起作用。

所以问题出现了,我如何检查开始忽略用户交互是否不起作用。我放了两个断点

一个在

UIApplication.shared.beginIgnoringInteractionEvents()

另一个在

UIApplication.shared.endIgnoringInteractionEvents()

当我按住退格按钮时,多个断点命中beginIgnoringInteractionEvents,而不命中endIgnoringInteractionEvents

可能的解决方案:

我已经找到了使用managedObjectContext?.performAndWait 而不是managedObjectContext?.perform 的方法。但这卡住了主线程。我必须在UILabel 中显示当前状态为searching...。如果我使用managedObjectContext?.performAndWait,它会省略阶段搜索并在一段时间后直接显示搜索结果。而不是这个,我更喜欢忽略用户交互并显示搜索操作的当前状态。

任何帮助将不胜感激。 T.I.A

【问题讨论】:

    标签: ios swift core-data nsoperationqueue uiapplication


    【解决方案1】:

    我想停下来

    tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
    

    当我准备搜索结果时。结果取自allContactSearchFetchResultController,但我将其分配给新的NSFetchedResultsController,但UITableView 根据allContactSearchFetchResultController 中的旧节数和行数调用managedObject,如下所示

    部分

    allContactSearchFetchResultController?.sections?.count
    

    allContactSearchFetchResultController?.sections[section].numberOfObject // There are more guard involved in this number of row fetching, for simplicity purpose i omitted those.
    

    但是当我将allContactSearchFetchResultController 分配给一个新的NSFetchedResultsController 时,表格视图会继续从cellForRowAt 请求IndexPath 的旧托管对象,因为表格视图不知道我已将它分配给新的NSFetchedResultsController .所以在这种情况下,我的解决方案是创建一个新的本地NSFetchedResultsController 准备它,在 managedObjectContext 的队列上对其执行提取。当结果准备好时切换到 mainQueue 并分配它。我的执行获取部分现在看起来像这样。

    //
    // ALL of this operation Run on MainQueue
    //
    let allFetchRequest = prepareCommonFetchRequest()
        allFetchRequest.predicate = NSPredicate.init(format: "name CONTAINS[cd] %@ || mobile_number CONTAINS[cd] %@", searchString, searchString)
    
        let tempAllContactSearchFetchResultController = NSFetchedResultsController.init(fetchRequest: allFetchRequest,
                                                                                managedObjectContext: managedObjectContext!,
                                                                                sectionNameKeyPath: "section_key",
                                                                                cacheName: nil)
    
    managedObjectContext?.perform {
        do {
            try self.allContactSearchFetchResultController?.performFetch()
            DispatchQueue.main.async {
                self.allContactSearchFetchResultController = tempAllContactSearchFetchResultController
                // calling the delegate which will reload the UITableView
            }
    
        } catch {
            print("Error occur")
            // TODO 
            // handle error here
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多