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

人气:337 发布:2022-10-16 标签: ios objective-c uisearchbar ios7 uinavigationcontroller

问题描述

我希望复制 Facebook Messenger 应用程序显示 UISearchBar 的方式.当您点击导航栏中的 leftBarButtonItem 时,UISearchBar 会从屏幕顶部向下显示/动画,当您取消时,它会从其起源的位置向上消失.

I'm looking to duplicate how the Facebook Messenger app shows the UISearchBar. When you tap the leftBarButtonItem in the navigationBar, the UISearchBar appears/animates from the top of the screen down, and when you cancel, it simply disappears upwards where it originated from.

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

I used to have my UISearchBar as the default setup in my table view's header (in storyboard), but now I'm wanting to do what I stated above but I am not sure where to begin. My search displayer controller is still in my storyboard, but I have deleted the searchBar from the tableView controller in the storyboard.

感谢您提供的任何帮助!

I appreciate any help offered!

推荐答案

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

Omitting detail of my own project where I make the same thing it looks as follows:

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,唯一的区别是我们使用同一张表来显示所有结果和过滤结果.我们还需要人工阴影视图.

Note: The general behavior of this construction is analogous to UISearchDisplayController, the only difference is that we use the same table to show all results and filtered result. Also we need artificial shadow view.

这是我的初始代码,它的行为与 FB People 视图控制器一致.在您发表评论后,我编写了标准 UISearchDisplayController 嵌入,但在将其注释掉后,因为它破坏了所需的 UI.无法更改其动画行为.

It was my initial code and its behavior coincides with FB People view controller. After your comment I wrote standard UISearchDisplayController embedding but after commented it out because it breaks desired UI. It is impossible to change its animation behavior.

352