如何从表格视图控制器的屏幕顶部显示UISearchBar

时间:2014-01-17 19:41:51

标签: ios objective-c ios7 uinavigationcontroller uisearchbar

我想复制Facebook Messenger应用程序显示UISearchBar的方式。当你点击navigationBar中的leftBarButtonItem时,UISearchBar会从屏幕顶部向下显示/动画,当你取消时,它会从它的起源处向上消失。

我曾经将我的UISearchBar作为我的表格视图标题中的默认设置(在故事板中),但现在我想要做我上面所说的但我不知道从哪里开始。我的搜索显示器控制器仍在我的故事板中,但我已从故事板中的tableView控制器中删除了searchBar。

感谢您提供的任何帮助!

3 个答案:

答案 0 :(得分:4)

省略我自己的项目的细节,我做了同样的事情,如下所示:

static CGFloat searchBarHeight = 64.0;

@implementation
{
    NSArray *_tableData; // active list of data to show in table at the moment
    NSMutableArray *_filteredContacts; // filtered list while search is active
    NSArray *_allContacts; // initial list of all data without search
    UIView* _searchBarWrapper;
    UIView *_shadowView;
    UISearchBar *_searchBar;
}

- (void)loadView
{
    [super loadView];

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(showSearchBar:)];

    _searchBarWrapper = [[UIView alloc] initWithFrame:CGRectMake(0, -searchBarHeight, self.navigationController.view.bounds.size.width, searchBarHeight)];
    _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 20.0, _searchBarContainer.bounds.size.width, searchBarHeight - 20.0)];
    [_searchBarContainer addSubview:_searchBar];
    [self.navigationController.view addSubview:_searchBarContainer];

    _shadowView = [[UIView alloc] initWithFrame:self.navigationController.view.bounds];
    _shadowView.backgroundColor = [UIColor blackColor];
    _shadowView.alpha = 0;
    [self.navigationController.view addSubview:_shadowView];
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideSearchBar:)];
    UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideSearchBar:)];
    [_shadowView addGestureRecognizer:tapGesture];
    [_shadowView addGestureRecognizer:swipeGesture];

    //_searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
    //_searchController.delegate = self;
    //_searchController.searchResultsDataSource = self;
    //_searchController.searchResultsDelegate = self;
}

- (void)showSearchBar:(id)sender
{
    [_searchBar becomeFirstResponder];
    [UIView animateWithDuration:0.25 animations:^{
        _searchBarWrapper.center = CGPointMake(_searchBar.center.x, searchBarHeight/2.0);
        _shadowView.alpha = 0.5;
    }];
}

- (void)hideSearchBar:(id)sender
{
    _searchBar.text = nil;
    [_tableView reloadData];

    [UIView animateWithDuration:0.25 animations:^{
        _searchBarWrapper.center = CGPointMake(_searchBar.center.x, -searchBarHeight/2.0);
        _shadowView.alpha = 0.0;
    }];
    [_searchBar resignFirstResponder];
    [_tableView reloadData];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    _tableData = _searchBar.isFirstResponder ? _filteredContacts : _allContacts;

    ....................
}


- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchText.length) {

        _filteredContacts = ....;

        _shadowView.alpha = 0.0;
        [_tableView reloadData];
    }
    else {
        _shadowView.alpha = 0.5;
    }
}

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

注意:此构造的一般行为类似于 UISearchDisplayController ,唯一的区别是我们使用相同的表来显示所有结果和过滤结果。我们还需要人工阴影视图。

这是我的初始代码,其行为与FB People视图控制器一致。 在您发表评论后,我编写了标准的 UISearchDisplayController 嵌入,但在评论之后,因为它打破了所需的UI。不可能改变它的动画行为。

答案 1 :(得分:4)

查看Apple的UICatalog示例代码。基本上只是以模态方式呈现您的UISearchController,您可以免费获得下拉动画。

答案 2 :(得分:0)

似乎Facebook隐藏了导航栏并在顶部显示了搜索栏和搜索显示控制器。尝试使用[self.navigationController setNavigationBarHidden:YES animated:NO];隐藏导航栏,并将搜索栏和搜索显示显示为tableView的子视图。 (我假设您知道“Search Bar and Search Display Controller”对象的工作方式

另一种方法是避免使用UITableViewController并在UIViewController中添加UITableView并隐藏导航栏下的搜索栏,这样当您隐藏导航栏时,搜索栏就会显示。

您还可以将UISearchBar设置为UINavigationBar的titleViewdescribed here