Как сохранить кнопку отмены в панели поиска, когда клавиатура отклоняется?
![enter image description here]()
![enter image description here]()
Я пытаюсь добиться такого же эффекта, как приложение Apple Contacts (левый снимок экрана). Кнопка отмены в UISearchBar включена, даже если клавиатура отклоняется. Мое приложение ведет себя по-другому (правый скриншот). Кнопка отмены автоматически отключается, когда клавиатура отклоняется. Пользователь должен нажать кнопку отмены один раз, чтобы включить его, а затем еще раз, чтобы фактически вызвать увольнение. Это не очень хороший пользовательский интерфейс. Как я всегда буду держать кнопку отмены включенной, как приложение Apple Contacts?
Технические детали:
Я не использую UISearchDisplayController
из-за некоторых требований к дизайну. Это всего лишь UISearchBar
с моим собственным контроллером пользовательского поиска. Кнопка отмены отображается с помощью [self.searchBar showsCancelButton:YES animated:YES]
. Клавиатура отклоняется с помощью [self.searchBar resignFirstResponder]
.
Ответы
Ответ 1
Вызов [self.searchBar resignFirstResponder]
отключит кнопку отмены. Следовательно, вы всегда должны обновить кнопку отмены, чтобы включить ее после вызова.
Objective-C
[searchBar resignFirstResponder];
UIButton *cancelButton = (UIButton *)[searchBar valueForKey:@"cancelButton"];
[cancelButton setEnabled:YES];
Swift
searchBar.resignFirstResponder()
if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton
cancelButton.isEnabled = true
}
По моему опыту, view.endEditing(true)
является проблемой. Потому что он также называется .resignFirstResponder
, если внутри представления есть UITextField, который содержится в UISearchBar.
https://developer.apple.com/reference/uikit/uiview/1619630-endediting
Ответ 2
Вы можете использовать API среды выполнения для доступа к кнопке отмены.
UIButton *btnCancel = [self.searchBar valueForKey:@"_cancelButton"];
[btnCancel setEnabled:YES];
Что касается вашего вопроса, вы не можете включить кнопку отмены, когда клавиатура отклоняется, например, нет обратного вызова.
Ответ 3
Для Swift 4.0
if let cancelButton : UIButton = searchBar.value(forKey: "cancelButton") as? UIButton{
cancelButton.isEnabled = true
}
Ответ 4
Так как iOS 7, все подчиненные UISearchBar на один уровень глубже. Это должно работать:
for (UIView *subView in searchBar.subviews) {
for (UIView *secondLevelSubview in subView.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[(UIButton *)view setEnabled:YES];
}
}
Все еще взломанный и может легко ломаться в следующей версии iOS.
Ответ 5
Вы можете сделать это:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self enableCancelButton];
}
- (void)enableCancelButton {
for (UIView *view in _seachBar.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[(UIButton *)view setEnabled:YES];
}
}
}
НО, это довольно хакерский метод, и я вполне уверен, что он вообще нахмурился Apple и потенциально может привести к отклонению приложения. Насколько мне известно, похоже, что нет другого способа сделать то, что вы пытаетесь сделать.
Ответ 6
Внедрите нижеуказанный метод делегата searchBarShouldEndEditing в свой код. Надеюсь, это поможет.
(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[[searchBar valueForKey:@"_cancelButton"] setEnabled:YES];
return YES;
}
Ответ 7
Здесь рекурсивное решение, которое работает для меня.
func enableButtons(_ view:UIView) {
for subView in view.subviews {
enableButtons(subView)
}
if let buttonView = view as? UIButton {
buttonView.isEnabled = true
}
}
Ответ 8
Вот простой способ:
searchBar.resignFirstResponder()
(searchBar.value(forKey: "_cancelButton") as? UIButton)?.isEnabled = true