Подтвердить что ты не робот

UISearchDisplayController.displaysSearchBarInNavigationBar позиционирует строку поиска в середине окна

Я пытаюсь использовать свойство displaysSearchBarInNavigationBar в классе iOS7 UISearchDisplayController для отображения строки поиска внутри панели навигации.

Используя пример AdvancedTableSearch от 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;
}

К сожалению, результат, который я получаю, выглядит следующим образом:

search bar in the wrong place

Строка поиска отображается в середине экрана, а не в элементе navigation.txt.

Что я делаю неправильно?

PS: Я не уверен, связано ли это, но self.searchDisplayController.navigationItem свойство nil.

4b9b3361

Ответ 1

Удалите строку поиска из представления таблицы. Использование displaysSearchBarInNavigationBar означает, что UISearchDisplayController позаботится о том, чтобы разместить в строке поиска строку поиска.

Кроме того, navigationItem будет равно nil, пока displaysSearchBarInNavigationBar не будет установлено значение YES. Элемент создается только при необходимости.

Ответ 2

У меня была такая же проблема, как и у вас, и потратил часы на поиск решения. В конечном итоге я пошел с созданием UISearchDisplayController программно.

Я создаю SearchTableViewController в Storyboard, а затем проделаю остальную часть работы программно. Делегатор контроллеров должен быть включен в заголовок, как вы заметите в приведенном ниже коде. Теперь интересная вещь возникает, когда я создаю searchBar. Обратите внимание, как я никогда не устанавливал его делегат? UISearchDisplayController делает это для меня, когда я создаю его с помощью searchBar. Тогда мне нужно установить делегат и источник для UISearchDislpayController и для searchResults; которые я делаю сразу после создания контроллера. Я не могу предоставить вам ответ "ПОЧЕМУ", что searchBar центрируется в представлении, когда он создан в Storyboard и установлен в displaysSearchBarInNavigationBar: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];
}

Строка поиска, отображаемая на панели навигации, не может иметь панель видимости.

ВАЖНО Система создает исключение, если вы устанавливаете showScopeBar свойство 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;
}