13

我正在尝试使用displaysSearchBarInNavigationBariOS7UISearchDisplayController类中的属性在导航栏中显示搜索栏。

使用Apple 的 AdvancedTableSearch 示例作为基础,我更改了代码以禁用范围(导航栏中不允许这样做)并将其设置displaysSearchBarInNavigationBar为 true,如下所示。

- (void)viewDidLoad
{
   [super viewDidLoad];

   // create a mutable array to contain products for the search results table
   self.searchResults = [NSMutableArray arrayWithCapacity:[self.products count]];
   self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
}

不幸的是,我得到的结果是这样的:

搜索栏在错误的位置

搜索栏出现在屏幕中间,而不是在 navigationItem 中。

我究竟做错了什么?

PS:我不确定它是否相关,但self.searchDisplayController.navigationItem属性是nil.

4

2 回答 2

14

从表格视图中删除搜索栏。使用displaysSearchBarInNavigationBar意味着 UISearchDisplayController 将负责为您将搜索栏放置在层次结构中。

此外,在设置为 YESnavigationItem之前将为零。displaysSearchBarInNavigationBar该项目仅在需要时创建。

于 2013-09-24T18:26:15.527 回答
3

我遇到了和你一样的问题,花了几个小时寻找解决方案。最终,我以UISearchDisplayController编程方式创建。

我在其中创建一个SearchTableViewControllerStoryboard然后以编程方式完成其余的工作。正如您将在下面提供的代码中注意到的那样,控制器委托必须包含在标头中。现在有趣的事情发生在我创建searchBar. 请注意我从未设置它的委托?当UISearchDisplayController我使用searchBar. 然后我只需要为 和 设置委托和UISearchDislpayControllersearchResults;我在创建控制器后立即执行此操作。我无法为您提供关于“为什么”在代码中创建并设置searchBar为时在视图中居中的答案,但我遇到了同样的问题,并发现以下是一个可行的解决方案。特别是考虑到我从来不需要调整任何大小:)StoryboarddisplaysSearchBarInNavigationBar:YES

SearchTableViewController.h

#import <UIKit/UIKit.h>

@interface SearchableTableViewController : UITableViewController<UISearchDisplayDelegate>
//I only need the SearchDisplayController Delegate because it magically has all the needed child delegates. :)
@end

SearchTableViewController.m

#import "SearchDisplayController.h"

@property (strong,nonatomic)  IBOutlet UITableView *acSearchTableView;
@property (retain,nonatomic)  UISearchBar *acSearchBar;
@property (retain,nonatomic)  UISearchDisplayController *searchDsplyCntrl;
@property (strong,nonatomic)  NSArray *unfilteredResults;
@property (strong,nonatomic)  NSMutableArray *filteredResults;

@implementation SearchTableViewController 

- (void) viewDidLoad {
    [super viewDidLoad];

    _acSearchBar = [[UISearchBar alloc]init];
    _acSearchBar.showsCancelButton = NO;

    /* NOTE: by default the placholer is centered. It can be left aligned with spaces */
    _acSearchBar.placeholder = @"Search                                                      ";

    _searchDsplyCntrl = [[UISearchDisplayController alloc]initWithSearchBar:_acSearchBar contentsController:self];
    _searchDsplyCntrl.delegate = self;
    _searchDsplyCntrl.searchResultsDelegate = self;
    _searchDsplyCntrl.searchResultsDataSource = self;
    _searchDsplyCntrl.displaysSearchBarInNavigationBar = YES;

    _unfilteredResults = [[NSArray alloc]initWithObjects:
                                               [ResultObj resultWithName:@"first"],
                                               [ResultObj resultWithName:@"second"],
                                               [ResultObj resultWithName:@"third"],
                                               [ResultObj resultWithName:@"forth"],
                                               [ResultObj resultWithName:@"fifth"],
                                               [ResultObj resultWithName:@"sixth"],
                                               [ResultObj resultWithName:@"seventh"],
                                               [ResultObj resultWithName:@"eigth"],nil];

    _filteredResults = [NSMutableArray arrayWithCapacity:[_unfilteredResults count]];

    [_acSearchTableView reloadData];
}

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

导航栏中显示的搜索栏不能有范围栏。

重要如果在导航栏中显示的搜索栏中将 showsScopeBar 属性设置为 YES,系统将引发异常。

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView == _searchDsplyCntrl.searchResultsTableView)
    {
        return [_filteredResults count];
    }
    else
    {
        return [_unfilteredResults count];
    }
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if ( cell == nil ) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Create a new Candy Object
    ResultObj *result = nil;

    // Check to see whether the normal table or search results table is being displayed and set the Candy object from the appropriate array
    if (tableView == _searchDsplyCntrl.searchResultsTableView)
    {
        result = [_filteredResults objectAtIndex:[indexPath row]];
    }
    else
    {
        result = [_unfilteredResults objectAtIndex:[indexPath row]];
    }

    // Configure the cell
    [[cell textLabel] setText:[result name]];
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];

    return cell;
}

#pragma mark Content Filtering

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    // Update the filtered array based on the search text and scope.

    // Remove all objects from the filtered search array
    [_filteredResults removeAllObjects];

    // Filter the array using NSPredicate
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
    NSArray *tempArray = [_unfilteredResults filteredArrayUsingPredicate:predicate];


    /*
    if(![scope isEqualToString:@"All"]) {
        // Further filter the array with the scope
        NSPredicate *scopePredicate = [NSPredicate predicateWithFormat:@"SELF.category contains[c] %@",scope];
        tempArray = [tempArray filteredArrayUsingPredicate:scopePredicate];
    }
    */

    _filteredResults = [NSMutableArray arrayWithArray:tempArray];
}

#pragma mark - UISearchDisplayController Delegate Methods

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    // Tells the table data source to reload when text changes
    [self filterContentForSearchText:searchString scope:
     [[_searchDsplyCntrl.searchBar scopeButtonTitles] objectAtIndex:[_searchDsplyCntrl.searchBar selectedScopeButtonIndex]]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;
}


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
    // Tells the table data source to reload when scope bar selection changes
    [self filterContentForSearchText:[_searchDsplyCntrl.searchBar text] scope:
     [[_searchDsplyCntrl.searchBar scopeButtonTitles] objectAtIndex:searchOption]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;
}
于 2014-10-31T19:11:03.820 回答