How to show a UISearchBar from top of screen for t

2019-03-21 14:31发布

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.

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!

3条回答
贼婆χ
2楼-- · 2019-03-21 14:42

It seems like Facebook hides the navigation bar and displays the Search Bar and Search Display Controller on top. Try hiding the navigation bar with [self.navigationController setNavigationBarHidden:YES animated:NO]; and presenting your Search Bar and Search Display as a childView of your tableView. (I assume you know how "Search Bar and Search Display Controller" object works)

Another way would be avoiding UITableViewController and adding a UITableView inside a UIViewController and hide the Search Bar under the Navigation Bar so when you hide the Navigation Bar, the Search Bar is visible.

You can also set the UISearchBar as the UINavigationBar's titleView as described here.

查看更多
甜甜的少女心
3楼-- · 2019-03-21 14:54

Check out Apple's UICatalog sample code. Basically just present your UISearchController modally and you get the dropdown animation for free.

查看更多
乱世女痞
4楼-- · 2019-03-21 14:55

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];
}

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.

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.

查看更多
登录 后发表回答