35 votes

Ajout programmatique de UISearchBar à UITableView

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

Dans l'Interface Builder, il existe une option permettant d'ajouter une Barre de recherche y Contrôleur d'affichage de recherche à un nib . Existe-t-il un moyen d'accomplir cette même tâche de manière programmatique ou est-il préférable pour moi d'abandonner l'option par défaut de l'outil de gestion de l'environnement ? UITableView et le transfert vers un UITableView afin que je puisse facilement ajouter le fichier UISearchbar ?

De plus, j'ai essayé de tester l'ajout d'une barre de recherche à mon site Web. UITableView (c'est là que je veux qu'il aille) via le code suivant dans mon fichier viewDidLoad mais il apparaît derrière l'en-tête de la section tableau et est donc invisible à moins que le tableau ne soit déroulé pour montrer ce qui serait autrement un espace blanc. Qu'est-ce qui se passe ?

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

[[self tableView] setTableHeaderView:testbar];

74voto

minux Points 1703

Pour ajouter une UISearchBar à un UITableView, il faut procéder comme suit :

  • Déclarer et initialiser UISearchBar
  • Déclarer et initialiser le UISearchDisplayController
  • Ajouter la barre de recherche à la tableView
  • Implémenter le délégué UISearchDisplayController
  • Dans le fichier d'en-tête, je déclare ma searchBar, mon 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 quoi, la 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 concernant l'initialisation de la cellule tableView, vous pouvez la trouver dans le code source téléchargeable :)

Lorsque le tableView est prêt, il est temps d'implémenter le UISearchDisplayControllerDelegate !

Le délégué dispose de nombreuses méthodes pour contrôler tous les aspects de la recherche, mais la plus importante est la suivante

- (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. Elle prend la searchString, effectue la recherche dans les éléments du tableau et renvoie 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;
}

C'est tout ! Cette méthode va effectuer une recherche en texte intégral dans tous les éléments. Lorsque la recherche est terminée, le 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) )

0 votes

Dans viewDidLoad, je dois également inclure cette ligne : searchDisplayController.searchResultsDataSource = self ; sinon la tableView n'est pas rechargée par shouldReloadTableForSearchString.

1 votes

Lien de téléchargement brisé.

0 votes

Pouvez-vous fournir le lien actif pour télécharger le code ?

21voto

Praveen-K Points 3135

Définissez le cadre de l'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-le en UIViewController .

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

  • Créer un IBOutlet de UITableView * myTableView et le connecter à Il suffit de modifier dans votre fichier VC, par exemple self en [self.myTableView reloadData];

Vous pouvez maintenant régler le tableView et une barre de recherche dans la plume elle-même.

UISearchDisplay Le contrôleur a sa 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 le tableau pour afficher les données de résultat dans le tableau, de sorte qu'il n'est pas nécessaire de créer un tableau distinct.

0 votes

Hmm donc cela résout le problème ? c'est pourquoi je vous ai dit de changer la position selon vos besoins. j'ai aussi mis à jour ma réponse :)

0 votes

Désolé, j'ai écrit le commentaire trop rapidement. Ce que je voulais dire, c'est que (0, 0, 320, 44) est le seul cadre possible, car l'affichage de l'en-tête de la table est toujours positionné en haut à gauche et prend toute la largeur, et la UISearchBar a toujours une hauteur de 44px. Vous pouvez définir ce que vous voulez, vous obtiendrez le cadre suivant

2 votes

Vous ajoutez un processus inutile, j'ai reproduit son problème et cela fonctionne : UISearchBar *testbar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,170,320,44)] ; [[self tableView] setTableHeaderView:testbar] ;

2voto

Legolas Points 6712

Mettre en œuvre - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section . Cela résoudra le problème de l'étiquette de section qui recouvre la vue d'en-tête.

1voto

Mr. Tann Points 546

Dans un mouvement rapide :

    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 une méthode de délégué pour recharger la vue de la 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()

    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X