web-dev-qa-db-fra.com

Ajouter UISearchBar par programme à UITableView

J'essaie d'ajouter un UISearchBar (avec sa logique de recherche correspondante) mais il y a un problème: j'utilise la UITableViewController de la sous-classe _ automatiquement générée UITableView au lieu d'une _ nib fichier, et tout manipuler par programmation en termes de vue de table.

Dans Interface Builder, il existe une option pour ajouter un barre de recherche et contrôleur d'affichage de recherche à un nib. Existe-t-il un moyen d'accomplir cette même tâche par programme ou est-ce en ma faveur d'abandonner le fichier UITableView par défaut et de le transférer vers un fichier nib UITableView personnalisé afin que je puisse facilement ajouter le UISearchbar?

De plus, j'ai essayé de tester simplement en ajoutant une barre de recherche à mon en-tête UITableView (qui est l'endroit où je veux qu'elle aille) via le code suivant dans mon implémentation viewDidLoad, mais cela apparaît derrière en-tête de section de table et est donc invisible à moins que la table ne défile pour montrer ce qui serait autrement un espace blanc. Qu'est-ce qui se passe avec ça?

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

[[self tableView] setTableHeaderView:testbar];
35
Gary Hedren

Définissez le cadre pour UISearchBar:

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

Si votre vue est une sous-classe de UITableViewController, changez-la en UIViewController.

  • Dans votre fichier nib, créez une vue et faites glisser votre tableView sous cette vue et modifiez la classe de référence pour cette vue dans votre UIViewController.

  • Créez un IBOutlet de UITableView * myTableView et connectez-le à votre fichier nib. il vous suffit de changer votre fichier VC par exemple self en [self.myTableView reloadData];

Vous pouvez maintenant ajuster le tableView et la barre de recherche dans la plume elle-même.

UISearchDisplay le contrôleur possède son propre UITableView qui affiche les résultats d'une recherche de données gérée par un autre contrôleur de vue. Ici, le searchDisplaycontroller combine la barre de recherche et la vue de table pour afficher les données de résultat dans la vue de table afin qu'il ne nécessite pas une vue de table distincte.

21
Praveen-K

Pour ajouter un UISearchBar à un UITableView, il y a ces choses à faire:

  • Déclarez et initialisez UISearchBar
  • Déclarez et initialisez le UISearchDisplayController
  • Ajouter la barre de recherche à la table
  • Implémenter le délégué UISearchDisplayController
  • Dans le fichier d'en-tête, je déclare mon searchBar, searchDisplayController et les tableaux qui contiennent les données à afficher.

ViewController.h:

#import 

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

    UISearchBar *searchBar;
    UISearchDisplayController *searchDisplayController;
}

@end

J'ai également ajouté 2 délégués à la classe: UISearchBarDelegate et UISearchDisplayDelegate, sans, le searchBar ne fonctionne tout simplement pas!

Initialiser les données:

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

Maintenant, nous devons initialiser nos deux objets, j'ai commenté le code pour expliquer ce que je fais:

//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.
}

J'ai décidé de sauter la partie sur l'initialisation des cellules tableView, vous pouvez la trouver dans le code source téléchargeable. :)

Lorsque la tableView est prête, il est temps d'implémenter UISearchDisplayControllerDelegate!

Le délégué dispose de nombreuses méthodes pour contrôler chaque aspect de la recherche, mais le plus important est

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

Cette méthode est appelée chaque fois que vous insérez un nouveau caractère dans la barre de recherche, vous prendrez la chaîne de recherche, effectuerez la recherche à travers les éléments du tableau et retournerez OUI.

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

C'est tout! Cette méthode effectuera une recherche en texte intégral dans tous les éléments. Lorsque la recherche se termine, la tableView se recharge. Voir le code source pour voir d'autres détails.

Télécharger le fichier source (Lien MIS À JOUR! (04.01.2016))

74
minux

Implémentez - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section. Cela résoudra le problème de la section Étiquette couvrant l'en-tête

2
Legolas

à Swift:

    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])

ajouter un délégué:

    class ViewController: UIViewController, UISearchBarDelegate

ajoutez maintenant la méthode déléguée pour recharger la vue de table:

    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()

    }
1
Mr. Tann