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

У меня возникла эта странная проблема, и я безуспешно пытался решить ее в течение последних нескольких часов.

У меня есть UISearchController, который появляется, когда пользователь нажимает UIBarButtonItem на панели навигации. Кнопка была создана с помощью IB, а затем подключена к его IBAction, а именно:

@IBAction func searchButtonTapped(sender: UIBarButtonItem) {
    searchController.active = true
    self.presentViewController(searchController, animated: true, completion: nil)
}

Это работает отлично. Появляется контроллер представления, и пользователь может вводить что-то.

В дополнение к простому нажатию элемента кнопки панели поиска я хочу дать пользователям больше возможностей с помощью этой кнопки. А именно, я хочу, чтобы они могли долго нажимать на него и принудительно касаться его, чтобы выполнять различные действия в моем приложении.

После взлома и поиска на SO некоторое время (и поскольку UIBarButtonItem не является представлением самого себя...), я нашел способ добавить некоторые распознаватели жестов в элемент кнопки панели поиска. Я добавил это в свой метод viewDidLoad.

if let searchBarButtonView = self.searchBarButtonItem.valueForKey("view") as? UIView where searchBarButtonView.respondsToSelector("addGestureRecognizer:") {

    if Settings.searchCollectionMagnifierGlassIconLongPressAction != .None {
        let longTapGr = UILongPressGestureRecognizer(target: self, action: "handleSearchBarButtonLongPressGesture:")
        longTapGr.minimumPressDuration = CFTimeInterval(Settings.searchCollectionMagnifierGlassIconLongPressActionTime)
        longTapGr.delegate = self
        searchBarButtonView.addGestureRecognizer(longTapGr)
    }

    if Settings.searchCollectionMagnifierGlassIconForceTouchAction != .None {
        let forceTouchGr = DFContinuousForceTouchGestureRecognizer()
        forceTouchGr.forceTouchDelegate = self
        forceTouchGr.triggeringForceTouchPressure = 2.0
        searchBarButtonView.addGestureRecognizer(forceTouchGr)
    }
}

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

Распознаватель жестов работает нормально. Для распознавателя жестов длинного нажатия это реализация для handleSearchBarButtonLongPressGesture::

func handleSearchBarButtonLongPressGesture(recognizer: UILongPressGestureRecognizer) {
    self.performSearchCollectionMagnifierGlassAction(Settings.searchCollectionMagnifierGlassIconLongPressAction)
}

А это реализация для performSearchCollectionMagnifierGlassAction:

func performSearchCollectionMagnifierGlassAction(action: Settings.SearchCollectionMagnifierGlassIconAction) {
    let action = Settings.searchCollectionMagnifierGlassIconLongPressAction

    if action == .ClearOldQueryAndSearch {
        self.searchController.searchBar.text = ""
        self.searchButtonTapped(self.searchBarButtonItem) // This is exactly as if the user tapped the search bar button item on his own... But it crashes when it gets called as a result of a gesture recognizer!
    }
}

(Я удалил другие ifs здесь, чтобы сделать код релевантным. Другие ifs только проверяют другие действия, и поэтому они не вызываются).

Длительное нажатие кнопки моей панели поиска работает нормально. Но приложение вылетает с:

*** Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Приложение пыталось модально представить активный контроллер

Если я просто нажму кнопку поиска, приложение не вылетит. Таким образом я могу показывать и скрывать UISearchController столько раз, сколько захочу. Как видите, долгое нажатие на кнопку поиска будет делать то же самое, что и обычное нажатие на кнопку, за исключением того, что оно очищает текстовое поле перед его отображением. Я попытался закомментировать строку, которая очищает панель поиска, но сбой все равно происходит. Учитывая, что при долгом нажатии и простом нажатии на кнопку поиска вызывается почти один и тот же код, я склонен думать, что этот сбой может быть, как ни странно, связан с распознавателем жестов.

Я также пытался отклонить searchController, даже если его нет, прежде чем очистить панель поиска и представить ее снова. Неудачно.

Наконец, я скопировал и вставил код с searchButtonTapped на performSearchCollectionMagnifierGlassAction. Там тоже не повезло.


person Andy Ibanez    schedule 16.01.2016    source источник
comment
Вы пытались добавить операторы print или вообще отладить performSearchCollectionMagnifierGlassAction? Возможно, по какой-то причине метод вызывается несколько раз.   -  person luk2302    schedule 16.01.2016
comment
Похоже, это так. Удивительно, почему я ничего не записал туда, чтобы увидеть, но это определенно вызывается как минимум дважды. Спасибо, ребята, не стесняйтесь добавлять это в качестве ответа.   -  person Andy Ibanez    schedule 17.01.2016


Ответы (1)


Ваш метод searchButtonTapped вызывается дважды: в обработчике жестов с длинным нажатием и непосредственно, когда представление UIBarButtonItem генерирует событие Touch Up.

Попробуйте закомментировать свой вызов searchButtonTapped или установить для свойства cancelsTouchesInView longTapGr значение true.

person Dim_ov    schedule 16.01.2016