Добавление UISearchBar программно в UITableView - PullRequest
35 голосов
/ 05 августа 2011

Я пытаюсь добавить UISearchBar (с соответствующей логикой поиска), но есть проблема: я использую автоматически созданный подкласс UITableViewController UITableView вместо отдельного файла nib и управляю всем программно с точки зрения табличного представления.

В Интерфейсном Разработчике есть возможность добавить Панель поиска и Search Display Controller к nib. Есть ли способ выполнить эту же задачу программным способом или мне выгодно отказаться от стандартного UITableView и перенести в пользовательский файл UITableView nib, чтобы я мог легко добавить UISearchbar?

Кроме того, я попытался протестировать, просто добавив строку поиска в мой заголовок UITableView (куда я хочу ее добавить) с помощью следующего кода в моей реализации viewDidLoad, но он отображается за заголовком раздела таблицы и, следовательно, невидим, если таблица не прокручивается вниз, чтобы показать, что в противном случае было бы пустым пространством. Что с этим?

UISearchBar *testbar = [[UISearchBar alloc] init];

[[self tableView] setTableHeaderView:testbar];

Ответы [ 4 ]

74 голосов
/ 13 февраля 2012

Чтобы добавить UISearchBar в UITableView, необходимо выполнить следующие действия:

  • Объявить и инициализировать UISearchBar
  • Объявить и инициализировать UISearchDisplayController
  • Добавить панель поискав tableView
  • Реализация делегата UISearchDisplayController
  • В заголовочном файле я объявляю свой searchBar, searchDisplayController и массивы, которые содержат данные для отображения.

ViewController.h:

#import 

@interface ViewController : UITableViewController
{
    NSArray *originalData;
    NSMutableArray *searchData;

    UISearchBar *searchBar;
    UISearchDisplayController *searchDisplayController;
}

@end

Я также добавил в класс 2 делегата: UISearchBarDelegate и UISearchDisplayDelegate, без, searchBar просто не работает!

Инициализация данных:

//ViewController.m

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        NSArray *group1 = [[NSArray alloc] initWithObjects:@"Napoli", @"Juventus", @"Inter", @"Milan", @"Lazio", nil];
        NSArray *group2 = [[NSArray alloc] initWithObjects:@"Real Madrid", @"Barcelona", @"Villareal", @"Valencia", @"Deportivo", nil];
        NSArray *group3 = [[NSArray alloc] initWithObjects:@"Manchester City", @"Manchester United", @"Chelsea", @"Arsenal", @"Liverpool", nil];

        originalData = [[NSArray alloc] initWithObjects:group1, group2, group3, nil];
        searchData = [[NSMutableArray alloc] init];
    }
    return self;
}

Теперь нам нужно инициализировать два наших объекта, я прокомментировал код, чтобы объяснить, что я делаю:

//ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
/*the search bar widht must be > 1, the height must be at least 44
(the real size of the search bar)*/

    searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
/*contents controller is the UITableViewController, this let you to reuse
the same TableViewController Delegate method used for the main table.*/

    searchDisplayController.delegate = self;
    searchDisplayController.searchResultsDataSource = self;
//set the delegate = self. Previously declared in ViewController.h

    self.tableView.tableHeaderView = searchBar; //this line add the searchBar
                                                //on the top of tableView.
}

Я решил пропустить часть об инициализации ячейки tableView, вы можете найти ее в загружаемом источникекод.:)

Когда tableView будет готов, пришло время реализовать UISearchDisplayControllerDelegate!

Делегат имеет много методов для управления каждым аспектом поиска, но наиболее важным является

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

Этот метод вызывается каждый раз, когда вы вставляете новый символ в строку поиска, вы берете searchString, выполняете поиск по элементам таблицы и возвращаете YES.

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [searchData removeAllObjects];
    /*before starting the search is necessary to remove all elements from the
      array that will contain found items */

    NSArray *group; 

/* in this loop I search through every element (group) (see the code on top) in
the "originalData" array, if the string match, the element will be added in a
new array called newGroup. Then, if newGroup has 1 or more elements, it will be
added in the "searchData" array. shortly, I recreated the structure of the
original array "originalData". */

    for(group in originalData) //take the n group (eg. group1, group2, group3)
                               //in the original data
    {
        NSMutableArray *newGroup = [[NSMutableArray alloc] init];
        NSString *element;

        for(element in group) //take the n element in the group
        {                    //(eg. @"Napoli, @"Milan" etc.)
            NSRange range = [element rangeOfString:searchString
                                     options:NSCaseInsensitiveSearch];

            if (range.length > 0) { //if the substring match
                [newGroup addObject:element]; //add the element to group
            }
        }

        if ([newGroup count] > 0) {
            [searchData addObject:newGroup];
        }

        [newGroup release];
    }

    return YES;
}

Вот и все!Этот метод будет выполнять полнотекстовый поиск по всему элементу.Когда поиск завершится, tableView перезагрузится.См. Исходный код для просмотра других подробностей.

Загрузить исходный файл (ссылка ОБНОВЛЕНА! (04.01.2016))

21 голосов
/ 05 августа 2011

Установить рамку для UISearchBar:

// Change the position according to your requirements
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 70, 320, 44)];

Если ваш вид является подклассом UITableViewController, измените его на UIViewController.

  • В вашем nib-файле создайте представление и перетащите табличное представление под этим просмотреть и изменить ссылочный класс для этого вида на ваш UIViewController.

  • Создайте IBOutlet из UITableView * myTableView и подключите его к Ваш файл пера. вам просто нужно изменить в своем файле VC, например, self на [self.myTableView reloadData];

Теперь вы можете отрегулировать tableView и строку поиска в самом пере.

UISearchDisplay контроллер имеет свой собственный UITableView, который отображает результаты поиска данных, управляемых другим контроллером представления. Здесь searchDisplaycontroller объединяет панель поиска и табличное представление для отображения данных результатов в табличном представлении, поэтому для него не требуется отдельное табличное представление.

2 голосов
/ 05 августа 2011

Реализация - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section. Это решит проблему раздела Label, охватывающего headerView

0 голосов
/ 18 сентября 2016

быстро:

    let searchController = UISearchController(searchResultsController: nil)

    let topConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 40)
    let leftConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0)
    let rightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 0)
    let heightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 44)
    searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false

    searchController.searchBar.addConstraint(heightConstraint)

    searchController.searchBar.placeholder = "Search Here"
    searchController.searchResultsUpdater = self
    searchController.searchBar.delegate = self

    self.view.addSubview(searchController.searchBar)

    self.view.addConstraints([topConstraint, leftConstraint, rightConstraint])

добавить делегата:

    class ViewController: UIViewController, UISearchBarDelegate

Теперь добавьте метод делегата для перезагрузки табличного представления:

    func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
        //add your custome code here after search a string
        tableView.reloadData()
    }

    func searchBarTextDidEndEditing(searchBar: UISearchBar) {
        //add your custome code here after finishing search 
        tableView.reloadData()

    }
...