#swift #uisearchbar
Вопрос:
Я столкнулся с этой ошибкой в своем приложении, и, по-видимому, она также появляется во многих других приложениях, особенно в приложениях Apple, таких как музыка, новости… Если вы используете функцию поиска в этих приложениях, введите что-нибудь в нее, а затем дважды щелкните строку поиска, чтобы открыть курсоры выделения текста. Удерживая первый курсор, перетащите его влево или вправо, не выходя за пределы последнего курсора. Продолжайте удерживать первый курсор и наберите что-нибудь на клавиатуре, приложение завершит работу с исключением NSRangeException.
Поскольку я использую UISearchBar в своем приложении, у меня та же проблема. Я не уверен, является ли это известной ошибкой или нет, но, похоже, я не могу найти никакой информации в Интернете. Есть ли обходной путь без изменения панели поиска на что-то другое? Также есть способ захватить событие touchesend (когда ваш палец покидает курсор после его перемещения), чтобы я мог продолжить изучение этой проблемы, я попробовал функцию touchesend UITextFieldDelegate, но она не работает.
Комментарии:
1. Разве вы не можете просто запретить выделение текста?
2. @GustavoConde Это окно поиска, оно должно работать как есть.
Ответ №1:
Я нашел обходной путь. Это не идеальное решение, так как оно не решает корень проблемы, но с точки зрения пользовательского опыта оно так же хорошо. Сначала вам нужно расширить UISearchTextFieldDelegate для вашего SearchViewController и переопределить методы textFieldDidChangeSelection и shouldChangeCharactersIn. Добавьте флаг, указывающий, активны ли двойные курсоры.
func textFieldDidChangeSelection(_ textField: UITextField) { if textField.selectedTextRange?.start != textField.selectedTextRange?.end { flag = false } else { flag = true } } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -gt; Bool { if !flag { searchBar.resignFirstResponder() // calculate the end position of the cursor let tempRangeS = textField.offset(from: textField.beginningOfDocument, to: textField.selectedTextRange!.start) let endPosition = textField.position(from: textField.beginningOfDocument, offset: tempRangeS string.count) // replace the selected text if let textRange = textField.selectedTextRange { textField.replace(textRange, withText: string) } searchBar.becomeFirstResponder() // move the cursor to the end position if endPosition != nil { textField.selectedTextRange = textField.textRange(from: endPosition!, to: endPosition!) } return false } return true }
Отказавшись от фокуса, вы эффективно удаляете выбор пользователя, который в первую очередь вызывает сбой, затем вычисляете, где должен находиться курсор после замены текста, и перемещаете курсор туда только после того, как снова установите фокус.