我试图达到与Apple的Contacts应用程序相同的效果(左侧截图)。即使键盘被解除,UISearchBar中的取消按钮也会启用。我的应用程序行为不同(右侧截图)。键盘解除后,取消按钮自动禁用。用户被迫点击取消按钮一次以启用它,然后再次点击实际触发解雇。这不是很好的用户体验。如何启用取消按钮,如Apple的联系人应用程序?
技术细节:
由于某些设计要求,我没有使用UISearchDisplayController
。这只是一个UISearchBar
与我自己的自定义搜索控制器。取消按钮使用[self.searchBar showsCancelButton:YES animated:YES]
显示。键盘被[self.searchBar resignFirstResponder]
解雇。
致电[self.searchBar resignFirstResponder]
将取消取消按钮。因此,您应该在调用后始终更新取消按钮以启用它。
Objective-C的
[searchBar resignFirstResponder];
UIButton *cancelButton = (UIButton *)[searchBar valueForKey:@"cancelButton"];
[cancelButton setEnabled:YES];
迅速
searchBar.resignFirstResponder()
if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton
cancelButton.isEnabled = true
}
根据我的经验,view.endEditing(true)
是问题所在。因为如果视图中有一个UITextField,它也被称为.resignFirstResponder
,它包含在UISearchBar中。
https://developer.apple.com/reference/uikit/uiview/1619630-endediting
您可以使用运行时API来访问取消按钮。
UIButton *btnCancel = [self.searchBar valueForKey:@"_cancelButton"];
[btnCancel setEnabled:YES];
就您的问题而言,当键盘被解除时,您无法启用取消按钮,就像没有回调一样。
对于Swift 4.0
if let cancelButton : UIButton = searchBar.value(forKey: "_cancelButton") as? UIButton{
cancelButton.isEnabled = true
}
从iOS 7开始,UISearchBar的所有子视图都更深一层。这应该工作:
for (UIView *subView in searchBar.subviews) {
for (UIView *secondLevelSubview in subView.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[(UIButton *)view setEnabled:YES];
}
}
仍然很hacky,可以轻松打破下一个iOS版本。
你可以这样做:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self enableCancelButton];
}
- (void)enableCancelButton {
for (UIView *view in _seachBar.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
[(UIButton *)view setEnabled:YES];
}
}
}
但这是一种非常糟糕的方法,而且我很确定它通常会被苹果公司所诟病,并可能导致该应用被拒绝。据我所知,似乎没有任何其他方法可以做你想做的事情。
在代码中实现下面的searchBarShouldEndEditing委托方法。希望它会有所帮助。
(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[[searchBar valueForKey:@"_cancelButton"] setEnabled:YES];
return YES;
}
这是一个适合我的递归解决方案。
func enableButtons(_ view:UIView) {
for subView in view.subviews {
enableButtons(subView)
}
if let buttonView = view as? UIButton {
buttonView.isEnabled = true
}
}
这是一个简单的方法:
searchBar.resignFirstResponder()
(searchBar.value(forKey: "_cancelButton") as? UIButton)?.isEnabled = true