2

我正在按照https://stackoverflow.com/a/14235624/855680上的答案设置我的动画UISearchBar,它以较小的宽度开始,然后在活动时扩展到 iPhone 屏幕的整个宽度。它按预期展开,只是根本没有出现“取消”按钮。我已经尝试setShowsCancelButton:animated同时调用searchBarTextDidBeginEditing:and searchDisplayControllerWillBeginSearch:,但无济于事。我错过了什么?这是我的代码:

HomeViewController.h

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

主视图控制器.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
4

4 回答 4

2

这是我自己想出来的!

我尝试以编程方式在新项目中创建UISearchBarUISearchDisplayController,但我没有在导航栏中添加搜索栏,而是将其添加到视图控制器的主视图中。它就是这样工作的,每当我单击搜索栏时,都会显示“取消”按钮,但当我停止编辑时它不会将大小调整回原始框架 - 但这是另一个讨论。之后,我回到这个项目并self.searchBar.showsCancelButton在我设置为 的每一行代码之后打印出来YES,结果发现值实际上是YES. 因此UINavigationBar,出于某种原因,它没有显示UISearchBar“取消”按钮。因此,我的解决方案是在导航栏的rightBarButtonItem.

开始时,导航栏如下所示:

在此处输入图像描述

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

在此处输入图像描述

当我单击键盘中的“搜索”或加号按钮时,搜索栏恢复为原来的大小,右侧栏按钮项消失。我的完整代码如下:

HomeViewController.h

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

主视图控制器.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
于 2013-09-29T04:43:33.443 回答
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];

}

于 2013-09-28T21:23:00.957 回答
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];
}

现在您将有一个带有取消按钮的搜索栏。

于 2014-02-24T11:27:45.147 回答
0

将搜索栏放在导航栏中有什么原因吗?我认为如果您将搜索栏放在视图中的某个位置,您的代码应该可以工作,如果您希望在其中放置一些东西,导航栏会很棘手,您通常会定义视图或项目来替换导航栏中的对象,例如 rightbarbuttonitem / leftbarbuttonitem 或标题

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
于 2013-09-29T07:40:33.597 回答