How do you keep the cancel button in the search ba

2020-06-01 05:27发布

enter image description here enter image description here

I'm trying to achieve the same effect as Apple's Contacts app (left screenshot). The cancel button in UISearchBar is enabled even when the keyboard is dismissed. My app behaves differently (right screenshot). The cancel button automatically becomes disabled when the keyboard is dismissed. The user is forced to tap the cancel button one time to enable it and then another time to actually trigger the dismissal. This is not good user experience. How would I always keep the cancel button enabled like Apple's Contacts app?

Technical Details:

I'm not using UISearchDisplayController due to some design requirements. This is just a UISearchBar with my own custom search controller. The cancel button is shown using [self.searchBar showsCancelButton:YES animated:YES]. The keyboard is dismissed using [self.searchBar resignFirstResponder].

11条回答
在下西门庆
2楼-- · 2020-06-01 05:53

For Swift 4.0

if let cancelButton : UIButton = searchBar.value(forKey: "cancelButton") as? UIButton{
    cancelButton.isEnabled = true
}
查看更多
贼婆χ
3楼-- · 2020-06-01 05:56

You could do this:

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self enableCancelButton];
}

- (void)enableCancelButton {
    for (UIView *view in _seachBar.subviews) {
        if ([view isKindOfClass:[UIButton class]]) {
            [(UIButton *)view setEnabled:YES];
        }
    }
}

BUT this is a pretty hackish method and I'm fairly certain it's generally frowned upon by Apple and could potentially lead to the app being rejected. As far as I know, there doesn't seem to be any other way to do what you're trying to do.

查看更多
成全新的幸福
4楼-- · 2020-06-01 05:58

Since iOS 7 all the subview of UISearchBar are one level deeper. This should work:

for (UIView *subView in searchBar.subviews) {
    for (UIView *secondLevelSubview in subView.subviews) {
        if ([view isKindOfClass:[UIButton class]]) {
           [(UIButton *)view setEnabled:YES];
        }
}

Still hacky and can easily break in the next iOS version.

查看更多
beautiful°
5楼-- · 2020-06-01 06:01

Call to [self.searchBar resignFirstResponder] will make the cancel button disabled. Hence, you should always update cancel button to enable after calling it.

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
}

In my experience, view.endEditing(true) is the problem. Because it's also called .resignFirstResponder if there's a UITextField inside the view, which is contained in UISearchBar.

https://developer.apple.com/reference/uikit/uiview/1619630-endediting

查看更多
Ridiculous、
6楼-- · 2020-06-01 06:02

Here's a simple way:

searchBar.resignFirstResponder()
(searchBar.value(forKey: "_cancelButton") as? UIButton)?.isEnabled = true
查看更多
登录 后发表回答