【问题标题】:UISearchDisplayController.displaysSearchBarInNavigationBar positions the search bar in the middle of the windowUISearchDisplayController.displays SearchBarOn NavigationBar 将搜索栏定位在窗口的中间
【发布时间】:2013-09-24 11:56:34
【问题描述】:

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

使用AdvancedTableSearch example from Apple 作为基础,我更改了代码以禁用范围(导航栏中不允许这样做)并将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

【问题讨论】:

    标签: ios objective-c ios7


    【解决方案1】:

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

    此外,navigationItem 将为零,直到 displaysSearchBarInNavigationBar 设置为 YES。该项目仅在需要时创建。

    【讨论】:

    • 听起来像是一个很大的重构,对吧?之后这款应用还会兼容 iOS6 吗?
    • 不,通过使用displaysSearchBarInNavigationBar,您的应用只能针对 iOS 7。
    • @NLemay,如果您在运行时测试 iOS7,并有条件地设置 displaysSearchBarInNavigatorBar 仅适用于 iOS7 及更高版本,它会优雅地退回到在 iOS6 导航栏下方显示搜索栏。
    • 好的,谢谢。所以我所要做的就是在检测到iOS 7时从UITableView中删除UISearchBar,并将displaySearchBarInNavigatorBar设置为true,它会起作用吗?对于 iOS 6 的兼容性,没有别的事可做?
    • 最后一句话是关键。 navigationItem 在 iOS7 中为 nil,直到 displaysSearchBarinNavigationBar 为 YES。我正在放置一个自定义的左栏按钮,该按钮不会在 iOS7 中显示(但在 iOS6 中显示)并且必须在将搜索栏放入导航栏后放置它。
    【解决方案2】:

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

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

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

    A search bar displayed in a navigation bar cannot have a scope bar.

    重要提示如果您设置了 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      相关资源
      最近更新 更多