UIApplication 的“beginIgnoringInteractionEvents”不工作
UIApplication's `beginIgnoringInteractionEvents` not working
首先,对于长问题,我深表歉意,我个人更喜欢简短而准确的问题。
背景
我正在 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
因为我想停下来
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
我正在准备搜索结果。结果取自 allContactSearchFetchResultController
,但我将其分配给新的 NSFetchedResultsController
,但 UITableView
根据 [=14] 中的旧节数和行数调用 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
时,table 视图继续从 cellForRowAt
请求位于 IndexPath
的旧托管对象,因为 table 视图不知道我已将它分配给新的 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
}
}
首先,对于长问题,我深表歉意,我个人更喜欢简短而准确的问题。
背景
我正在 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
因为我想停下来
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
我正在准备搜索结果。结果取自 allContactSearchFetchResultController
,但我将其分配给新的 NSFetchedResultsController
,但 UITableView
根据 [=14] 中的旧节数和行数调用 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
时,table 视图继续从 cellForRowAt
请求位于 IndexPath
的旧托管对象,因为 table 视图不知道我已将它分配给新的 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
}
}