当作为子视图添加到UINavigationBar时,UISearchBar不显示“取消”按钮 [英] UISearchBar does not display Cancel button when added as subview to UINavigationBar

查看:132
本文介绍了当作为子视图添加到UINavigationBar时,UISearchBar不显示“取消”按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照 http://stackoverflow.com/a/14235624/855680 的答案为我的动画 UISearchBar 以较小的宽度开始,然后在活动时扩展到iPhone屏幕的全宽。它按预期展开,但取消按钮根本不显示。我试着在 searchBarTextDidBeginEditing:中调用 setShowsCancelButton:animated > searchDisplayControllerWillBeginSearch:,但没有效果。我缺少什么?这是我的代码:



HomeViewController.h

  #import< UIKit / UIKit.h> 
@interface HomeViewController:UIViewController< UISearchBarDelegate,UISearchDisplayDelegate>
@end

HomeViewController.m b
$ b

  #importHomeViewController.h

@interface HomeViewController()

@property强,非原子)UISearchDisplayController * sdc;
@property(strong,nonatomic)UISearchBar * searchBar;

@end

@implementation HomeViewController

- (void)viewDidLoad {
[super viewDidLoad];

//将虚拟按钮添加到导航栏。
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];

//添加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];
}

//从这一点开始,几乎从StackOverflow的复制粘贴答案。
- (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]){
//恢复到正常状态。
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];
}

//尝试捕获编辑事件并显示取消按钮。
// BOTH DO NOT WORK。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
}

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
[controller.searchBar setShowsCancelButton:YES animated:YES];
}

@end


解决方案



我尝试以编程方式创建 UISearchBar UISearchDisplayController 在新项目中,但是不是添加在导航栏中的搜索栏,我将它添加到视图控制器的主视图。它的工作方式,取消按钮显示每当我点击搜索栏,除了它不调整大小回到原始帧,当我停止编辑 - 但这是另一个讨论。之后,我回到这个项目,并在每行代码后打印出 self.searchBar.showsCancelButton ,我将其设置为 YES ,结果是值是,事实上, YES 。因此,由于某种原因, UINavigationBar 不会显示 UISearchBar 的取消按钮。然后,我的解决方案是在导航栏的 rightBarButtonItem 中创建一个假的取消按钮。



,导航栏如下所示:





然后,当我点击搜索栏时,我将其展开为一个宽度,足以覆盖左侧的两个按钮项,但留下一些空间以保持右侧栏按钮项可见。然后,右侧栏按钮项作为取消按钮(我只是使用一个系统添加按钮为演示)。





当我点击键盘上的搜索加号按钮,搜索栏将恢复其旧尺寸,右侧栏按钮项目将消失。我的完整代码如下:



HomeViewController.h

 code> #import< UIKit / UIKit.h> 
@interface HomeViewController:UIViewController< UISearchBarDelegate>
@end

HomeViewController.m b
$ b

  #importHomeViewController.h

@interface HomeViewController()
@property(strong,nonatomic) UISearchBar * searchBar;
@end

@implementation HomeViewController

- (void)viewDidLoad {
[super viewDidLoad];

//只有一些按钮,搜索栏将在活动时重叠。
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 {
//设置一个假的取消按钮。
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];

//将搜索栏放到前面,因为添加了右边栏按钮
// item以某种方式将其放在UIBarButtonItems后面。
[self.navigationController.navigationBar bringSubviewToFront:self.searchBar];
return YES;
}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {

//返回旧框架。
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^(){
self.searchBar.frame = CGRectMake(100,0,150,44)
} completion:nil];

//删除取消按钮。
self.navigationItem.rightBarButtonItem = nil;

[self.navigationController.navigationBar bringSubviewToFront:self.searchBar];

return YES;
}

- (void)stopEditing {
[self.searchBar resignFirstResponder];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self stopEditing];
}

@end


I'm following the answer at http://stackoverflow.com/a/14235624/855680 to animate my UISearchBar which starts off with a smaller width, then expands to the full width of the iPhone screen when active. It expands as expected, except that the Cancel button does not appear at all. I've tried calling setShowsCancelButton:animated in both searchBarTextDidBeginEditing: and searchDisplayControllerWillBeginSearch:, but to no avail. What am I missing? Here's my code:

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

解决方案

Figured this out myself!

I tried programmatically creating the UISearchBar and the UISearchDisplayController in a new project, but instead of adding the search bar in the navigation bar, I added it to the main view of a view controller. It worked that way, the Cancel button shows whenever I click on the search bar, except that it doesn't resize back to the original frame when I stop editing--but that's for another discussion. Afterwards, I went back to this project and printed out self.searchBar.showsCancelButton after every line of code where I set it to YES, and it turned out the value is, in fact, YES. So it is the UINavigationBar that, for some reason, does not show the UISearchBar's Cancel button. My solution, then, was to create a fake "Cancel" button in the navigation bar's rightBarButtonItem.

On start, the navigation bar looks like this:

Then, when I click on the search bar, I expand it to a width that's just enough to cover the two left bar button items, but leave some space to keep the right bar button item visible. Then, that right bar button item serves as the Cancel button (I just used a system "Add" button for demo's sake).

When I click on "Search" in the keyboard, or on the plus button, the search bar reverts to its old size and the right bar button item disappears. My full code is below:

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

这篇关于当作为子视图添加到UINavigationBar时,UISearchBar不显示“取消”按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆