У меня возникла эта странная проблема, и я безуспешно пытался решить ее в течение последних нескольких часов.
У меня есть 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
. Там тоже не повезло.
print
или вообще отладитьperformSearchCollectionMagnifierGlassAction
? Возможно, по какой-то причине метод вызывается несколько раз. - person luk2302   schedule 16.01.2016