我正在关注https://stackoverflow.com/a/14235624/855680的答案,为我的UISearchBar
设置动画,以较小的宽度开始,然后在激活时扩展到iPhone屏幕的整个宽度。它按预期展开,但“取消”按钮根本不显示。我尝试在setShowsCancelButton:animated
和searchBarTextDidBeginEditing:
中调用searchDisplayControllerWillBeginSearch:
,但无济于事。我错过了什么?这是我的代码:
HomeViewController.h
#import <UIKit/UIKit.h>
@interface HomeViewController : UIViewController <UISearchBarDelegate, UISearchDisplayDelegate>
@end
HomeViewController.m
#import "HomeViewController.h"
@interface HomeViewController ()
@property (strong, nonatomic) UISearchDisplayController *sdc;
@property (strong, nonatomic) UISearchBar *searchBar;
@end
@implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Add dummy buttons to navigation bar.
UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:nil];
UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:nil];
[self.navigationItem setLeftBarButtonItems:@[btn1, btn2] animated:YES];
// Add UISearchBar.
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(100, 0, 150, 44)];
self.sdc = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.sdc.delegate = self;
[self.navigationController.navigationBar addSubview:self.searchBar];
}
// From this point onwards, pretty much copy-paste from the StackOverflow answer.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(adjustFrame:) name:UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:@selector(adjustFrame:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)adjustFrame:(NSNotification *) notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationBeginsFromCurrentState:YES];
if ([[notification name] isEqual:UIKeyboardWillHideNotification]) {
// revert back to the normal state.
self.searchBar.frame = CGRectMake (100, 0, 150, 44);
}
else {
//resize search bar
self.searchBar.frame = CGRectMake (0,0,320,self.searchBar.frame.size.height);
}
[UIView commitAnimations];
}
// Try to catch the editing event and display the Cancel button.
// BOTH DON'T WORK.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
[controller.searchBar setShowsCancelButton:YES animated:YES];
}
@end
答案 0 :(得分:2)
自己想出来了!
我尝试在新项目中以编程方式创建UISearchBar
和UISearchDisplayController
,但我没有在导航栏中添加搜索栏,而是将其添加到视图控制器的主视图中。它以这种方式工作,每当我点击搜索栏时,“取消”按钮就会显示,但是当我停止编辑时它不会调整回原始帧 - 但这是另一个讨论。之后,我回到了这个项目并在我将其设置为self.searchBar.showsCancelButton
的每行代码后打印出YES
,事实证明该值是YES
。因此,UINavigationBar
由于某种原因未显示UISearchBar
的取消按钮。我的解决方案是在导航栏rightBarButtonItem
中创建一个虚假的“取消”按钮。
开始时,导航栏如下所示:
然后,当我点击搜索栏时,我将其展开到足以覆盖两个左栏按钮项的宽度,但留出一些空格以保持右栏按钮项可见。然后,右边的条形按钮项目用作取消按钮(为了演示,我只使用了系统“添加”按钮)。
当我点击键盘上的“搜索”或加号按钮时,搜索栏将恢复为旧尺寸,右侧栏按钮项目将消失。我的完整代码如下:
<强> HomeViewController.h 强>
#import <UIKit/UIKit.h>
@interface HomeViewController : UIViewController <UISearchBarDelegate>
@end
<强> HomeViewController.m 强>
#import "HomeViewController.h"
@interface HomeViewController ()
@property (strong, nonatomic) UISearchBar *searchBar;
@end
@implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Just some buttons that the search bar will overlap when active.
UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:nil];
UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:nil];
[self.navigationItem setLeftBarButtonItems:@[btn1, btn2] animated:YES];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(100, 0, 150, 44)]; self.searchBar.delegate = self;
[self.navigationController.navigationBar addSubview:self.searchBar];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Set a fake Cancel button.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(stopEditing)];
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^(){
self.searchBar.frame = CGRectMake(0, 0, 280, 44);
} completion:nil];
// Bring search bar to the front because adding a right bar button
// item somehow puts it behind the UIBarButtonItems.
[self.navigationController.navigationBar bringSubviewToFront:self.searchBar];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
// Go back to the old frame.
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^(){
self.searchBar.frame = CGRectMake(100, 0, 150, 44);
} completion:nil];
// Remove the "Cancel" button.
self.navigationItem.rightBarButtonItem = nil;
[self.navigationController.navigationBar bringSubviewToFront:self.searchBar];
return YES;
}
- (void)stopEditing {
[self.searchBar resignFirstResponder];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self stopEditing];
}
@end
答案 1 :(得分:1)
您应该设置UISearchBar的委托 self.searchBar.delegate = self;
- (void)viewDidLoad {
[super viewDidLoad];
// Add dummy buttons to navigation bar.
UIBarButtonItem *btn1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:nil];
UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:nil];
[self.navigationItem setLeftBarButtonItems:@[btn1, btn2] animated:YES];
// Add UISearchBar.
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(100, 0, 150, 44)];
self.sdc = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.sdc.delegate = self;
self.searchBar.delegate = self;
[self.navigationController.navigationBar addSubview:self.searchBar];
}
答案 2 :(得分:0)
是否有任何理由将搜索栏放在导航栏中?我认为如果您将搜索栏放在视图中的某个位置,您的代码应该可以正常工作,如果您想在其中添加内容,导航栏很棘手您通常会定义视图或项目以替换导航栏中的对象,如rightbarbuttonitem / leftbarbuttonitem或标题
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
答案 3 :(得分:0)
这是iOS7最简单的解决方案。
- (void) viewDidLoad
{
self.navigationItem.leftBarButtonItem = LEFT_ITEM;
self.navigationItem.rightBarButtonItem = SEARCH_ICON;
}
- (void)searchIconPressed
{
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.rightBarButtonItem = nil;
self.navigationItem.titleView = self.searchBar;
UIBarButtonItem* cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelSearch)];
[self.navigationItem setRightBarButtonItem:cancel animated:YES];
[self.searchBar becomeFirstResponder];
}
现在您将有一个带取消按钮的搜索栏。