UISearchController in a UIViewController

je cherche à créer une fonctionnalité similaire à L'application maps D'Apple dans Swift. Est-ce qu'il y a de toute façon d'intégrer un UISearchController dans une vue régulière (i.e.: non UITableView). Le fait d'en laisser tomber un dans le Storyboard résulte en un crash après avoir cliqué à l'intérieur de la barre de recherche connectée. Ou y a-t-il un moyen d'atteindre ce résultat avec une Visionutable?

12
demandé sur UncleAlfonzo 2014-10-17 07:51:44

4 réponses

j'ai ajouté une barre de recherche et un contrôleur D'affichage de recherche dans mon contrôleur de vue dans le storyboard. Le contrôleur view ne contient que la barre de recherche et le contrôleur search display et ne possède pas sa propre TableView. Lorsque vous ajoutez la barre de recherche dans votre controller view, elle définit votre controller view comme delegate automatiquement.

maintenant la barre de recherche et le contrôleur D'affichage de recherche a une vue de table de lui-même qu'il utilise pour afficher les résultats de recherche quand vous cliquez dans la boîte et commence à taper. Cette vue table attend de votre contrôleur de vue qu'il fournisse les implémentations des fonctions numberOfRowsInSection et cellForRowAtIndexPath pour qu'il affiche les données correctement.

Lorsque vous lancez votre projet sans ces et tapez dans la barre de recherche, vous obtiendrez l'erreur suivante:-

tableView: numberOfRowsInSection:]: selector non reconnu envoyé à l'instance 0x7fbf63449660 *** Fin de l'application pour cause de non-lieu exception "NSInvalidArgumentException

si vous voyez, l'erreur est à la méthode de sectiondu nombre.

changer la définition de votre contrôleur de vue de

class ViewController: UIViewController

à

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource

et mettre en œuvre les méthodes requises qui sont: -

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return UITableViewCell()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 0
}

je viens d'ajouter des valeurs de retour par défaut dans les méthodes ci-dessus.

Maintenant, si vous filtrez vos données source dans vos méthodes searchviewdelegate et mettez en place votre nombre de lignes et d'informations de cellules dans les deux méthodes ci-dessus correctement, il devrait fonctionner.

Espérons que cette aide!

2
répondu Rajeev Bhatia 2014-10-17 06:09:05

si vous voulez utiliser UISearchController avec une vue non utilisable, voici comment je l'ai fait.

puisque le UISearchController n'est pas (encore!) soutenu par IB, vous faites pas besoin d'ajouter quoi que ce soit dans elle, comme un UISearchBar .

@interface UIViewControllerSubclass () <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>

@property (strong, nonatomic) UISearchController *searchController;

@end

@implementation UIViewControllerSubclass

- (void)viewDidLoad
{        
    [super viewDidLoad];
    // Do any custom init from here...

    // Create a UITableViewController to present search results since the actual view controller is not a subclass of UITableViewController in this case
    UITableViewController *searchResultsController = [[UITableViewController alloc] init];

    // Init UISearchController with the search results controller
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];

    // Link the search controller
    self.searchController.searchResultsUpdater = self;

    // This is obviously needed because the search bar will be contained in the navigation bar
    self.searchController.hidesNavigationBarDuringPresentation = NO;

    // Required (?) to set place a search bar in a navigation bar
    self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;

    // This is where you set the search bar in the navigation bar, instead of using table view's header ...
    self.navigationItem.titleView = self.searchController.searchBar;

    // To ensure search results controller is presented in the current view controller
    self.definesPresentationContext = YES;

    // Setting delegates and other stuff
    searchResultsController.tableView.dataSource = self;
    searchResultsController.tableView.delegate = self;
    self.searchController.delegate = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;        
}

@end

j'espère que c'est suffisant pour travailler :-)

alors, bien sûr, vous devez au moins mettre en œuvre Uitable Viewdelegate, Uitable Viewdatasource, UISearchResultsUpdater méthodes.

Profitez-en!

37
répondu adauguet 2014-11-10 15:44:16

J'essaie de comprendre UISearchController moi-même. Le paramétrer au titleView est commode, mais sur une de mes pages, j'ai dû mettre le searchBar près du haut du UIViewController :

// Add a normal View into the Storyboard.
// Set constraints:
// - height: 44
// - leading and trailing so that it spans the width of the page
// - vertical position can be anywhere based on your requirements, like near the top
@IBOutlet weak var searchContainerView: UIView!

var searchResultsController = UISearchController()

override func viewDidLoad() {
    // TODO: set the searchResultsController to something
    let controller = UISearchController(searchResultsController: nil)
    // have the search bar span the width of the screen
    controller.searchBar.sizeToFit()
    // add search bar to empty View
    searchContainerView.addSubview(controller.searchBar)
    searchResultsController = controller
}

mise à jour:

après avoir implémenté UISearchController dans un ou deux projets, je me suis trouvé à graviter vers l'approche de @adauguet consistant à intégrer la barre de recherche dans la barre de Navigation.

voici le code de Swift. Une différence cependant est qu'il ne définit pas la barre de recherche delegate, puisque searchResultsUpdater écoute déjà les modifications de texte.

override func viewDidLoad() {
    super.viewDidLoad()
//        locationManager.delegate = self
//        locationManager.desiredAccuracy = kCLLocationAccuracyBest
//        locationManager.requestWhenInUseAuthorization()
//        locationManager.requestLocation()
    let locationSearchTable = storyboard!.instantiateViewControllerWithIdentifier("LocationSearchTable") as! LocationSearchTable
    resultSearchController = UISearchController(searchResultsController: locationSearchTable)
    resultSearchController?.searchResultsUpdater = locationSearchTable
    let searchBar = resultSearchController!.searchBar
    searchBar.sizeToFit()
    searchBar.placeholder = "Search for places"
    navigationItem.titleView = resultSearchController?.searchBar
    resultSearchController?.hidesNavigationBarDuringPresentation = false
    resultSearchController?.dimsBackgroundDuringPresentation = true
    definesPresentationContext = true
}

aussi, j'ai écrit un billet de blog qui crée un projet à partir de zéro qui utilise UISearchController pour afficher des résultats de recherche de carte. Il fait aussi d'autres choses que vous pourriez vouloir dans un projet de carte, comme obtenir l'emplacement de l'utilisateur, de laisser tomber des pins, analyser des placemarks dans une adresse d'une ligne, et créer boutons d'appel qui vous amènent à Apple Maps pour les directions de conduite.

http://www.thorntech.com/2016/01/how-to-search-for-location-using-apples-mapkit /

le billet de blog est assez long, donc voici le git repo associé si vous voulez juste passer au code:

https://github.com/ThornTechPublic/MapKitTutorial

6
répondu Robert Chen 2016-01-12 21:40:17

j'ai eu quelques difficultés à passer de SearchDisplayController dans UIViewController à SearchController dans ViewController parce que l'implémentation de SearchController n'est pas si intuitive. Mais vous pouvez simplement ajouter searchcher à partir de SearchController lui-même dans n'importe quelle vue. Vous ne pouvez pas définir la contrainte parce que la barre de recherche se déplace vers le haut lorsque vous la focalisez/la sélectionnez (si vous savez comment définir la contrainte à seachController.searchbar après l'avoir ajouté à n'importe quelle vue, faites-le moi savoir!). Ci-dessous, je vais partager une liste de contrôle que j'ai trouvé très importante/utile lors de la mise en œuvre de SearchController dans ViewController.

/ / vous pouvez simplement ajouter searcher à n'importe quelle vue. Il se déplacerait automatiquement vers le haut pour montrer le tableView comme la magie. Mais pour cette raison, vous ne pouvez pas définir contrainte à la barre de recherche à la vue placeholder à laquelle vous l'ajoutez.

[self.searchBarPlaceHolderView addSubview:self.searchController.searchBar];

/ / vous en avez besoin pour empêcher la barre de recherche de tomber lorsque vous la focalisez / la sélectionnez. Vous voudriez mettre ceci à non si vous ajoutez searchBar à titleview de la barre de navigation.

self.searchController.hidesNavigationBarDuringPresentation = YES;

/ / assurez-vous de régler ce paramètre dans votre viewController

self.extendedLayoutIncludesOpaqueBars = true;
self.definesPresentationContext = YES;

/ / vous devez également donner au contrôleur de recherche un tableViewController qui peut être affiché. Vous pouvez aussi faire juste vous-même.searchResultsController = [[UITableView alloc] init] pour un générique.

self.searchResultsController = (UITableViewController *)[ [UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"searchResultsTableViewController"];

self.searchResultsController.tableView.dataSource = self;
self.searchResultsController.tableView.delegate = self;
self.searchResultsController.definesPresentationContext = NO;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.searchResultsController];
0
répondu coolcool1994 2017-11-12 15:44:33