`BeginIgnoringInteractionEvents` приложения UIA не работает - PullRequest
0 голосов
/ 07 мая 2018

Прежде всего, мои извинения за длинный вопрос, я лично предпочитаю короткий точный вопрос.

Фон

Я разрабатываю функцию поиска в 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
        }
    }

Я прекратил взаимодействие с пользователем, чтобы пользователь больше не мог вводить с клавиатуры, пока этот поиск не закончится. Если инициирован многократный поиск, представление таблицы перезагружается на неопределенное время, и приложение падает при доступе к

managedObject = allContactSearchFetchResultController?.object(at: indexPath)

С UITableViewDataSource

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

Чтобы запустить одну операцию поиска, я начал игнорировать взаимодействие с пользователем. После окончания поиска я прекращаю игнорировать взаимодействие с пользователем.

Задача

Работает нормально, пока я не увижу, нажимая и удерживая кнопку возврата, начало игнорировать взаимодействие с пользователем не работает.

enter image description here

Таким образом, возникает вопрос, как я могу проверить, что начало игнорирования взаимодействия с пользователем не работает. Я поставил две точки останова

один в

UIApplication.shared.beginIgnoringInteractionEvents()

другой на

UIApplication.shared.endIgnoringInteractionEvents()

когда я нажимаю и удерживаю кнопку возврата, несколько точек останова нажимают на beginIgnoringInteractionEvents, не нажимая endIgnoringInteractionEvents.

Возможное решение:

Я уже нашел способ обойти, используя managedObjectContext?.performAndWait вместо managedObjectContext?.perform. Но это застряло в главной теме. Я должен показать в UILabel, что текущий статус searching.... Если я использую managedObjectContext?.performAndWait, он пропускает этап поиска и через некоторое время показывает результаты поиска. Вместо этого я предпочитаю игнорировать взаимодействие с пользователем и показывать текущий статус операции поиска.

Любая помощь будет оценена. T.I.A

1 Ответ

0 голосов
/ 08 мая 2018

Как я хотел остановиться

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

пока я готовлю результат поиска. Результат был взят из allContactSearchFetchResultController, но я назначил его новому NSFetchedResultsController, но UITableView вызывал managedObject на основе старого счетчика разделов и строк в allContactSearchFetchResultController следующим образом

Раздел

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, табличное представление продолжает запрашивать старый управляемый объект в IndexPath с cellForRowAt, потому что табличное представление не знает, что я присвоил его новому NSFetchedResultsController , Таким образом, в этом сценарии мое решение состоит в том, чтобы создать новый локальный NSFetchedResultsController, подготовить его, выполнить выборку для него в очереди управляемогоObjectContext. Пока результаты готовы, переключитесь на 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
    }
}
...