web-dev-qa-db-fra.com

Comment implémenter UISearchController dans UITableView - Swift

Je suis un débutant chez Swift et j'essaie d'ajouter une fonctionnalité de recherche à ma UITableView qui se trouve dans une classe UIViewController. J'ai beaucoup cherché sur Google et j'ai découvert que UISearchDisplayController était obsolète et remplacé par UISearchController. Lorsque j'ai essayé de rechercher des tutoriels, je n'en ai trouvé aucun spécifiquement pour UITableView. Certains d'entre eux étaient destinés à être implémentés dans UITableViewController. Donc, voici mes questions:

  1. Peut-on implémenter UISearchController dans une UITableView qui est dans une classe UIViewController? (Je suppose que nous pouvons)

  2. Si possible, veuillez convertir cette ligne de codes écrite en Objective-C. Ou s'il y a de très bons tutoriels, s'il vous plaît faites le moi savoir.

    @property (strong, nonatomic) UISearchController *searchController;
    
    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;
    

La source

EDIT: J'essaie d'attribuer le programme de mise à jour des résultats de la recherche en tant que

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {

    override func viewDidLoad() {

       super.viewDidLoad()
       self.view.backgroundColor = UIColor.blackColor() 
       self.addTableViewWithSection() 
       self.searchResultsController = UITableViewController()           
       var controller = UISearchController(searchResultsController: nil)            
       controller.searchResultsUpdater = self           
       controller.dimsBackgroundDuringPresentation = false   
    }
}

* Cependant, sur la ligne controller.searchResultsUpdater = self, j'obtiens l'erroor car impossible d'affecter une valeur de type "ViewController" à une valeur de type "UISearchResultsUpdating?" .. Donc je doute vraiment de pouvoir utiliser UISearchController dans la classe de type UIViewController.

38
user4790024

Oui, la façon dont la recherche fonctionne a été radicalement modifiée pour devenir ce que je considère être un meilleur système. Le nouveau système est bien meilleur et va droit au but pour la plupart des implémentations simples. Son utilisation est assez simple.

Tout d’abord, assurez-vous que votre classe se conforme au protocole UISearchResultsUpdating.

class MyTableViewController: UITableViewController, UISearchResultsUpdating {}

Ajoutez-y la propriété du contrôleur de recherche:

class MyTableViewController: UTableViewController, UISearchResultsUpdating {
    let searchController = UISearchController(searchResultsController: nil)
}

Ajoutez la barre de recherche dans viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.sizeToFit()
    self.tableView.tableHeaderView = searchController.searchBar
}

Et enfin, implémentez la méthode updateSearchResults:for qui provient du protocole UISearchResultsUpdating:

func updateSearchResults(for searchController: UISearchController) {

}

Votre implémentation de cette méthode dépendra bien sûr de l'endroit où vous recherchez les données. Il mettra à jour votre vue de table actuelle avec le contenu de votre recherche au fur et à mesure que vous les tapez. Assurez-vous de mettre à jour votre source de données et de recharger la vue tabulaire dans la méthode updateSearchResultsForSearchController. De nouveau, il est mis à jour au fur et à mesure de la frappe. Assurez-vous donc que si vos données de recherche sont volumineuses ou si vous effectuez une recherche sur Internet, ajoutez un peu de concurrence dans cette méthode.

Si vous souhaitez utiliser un autre contrôleur pour renseigner vos résultats de recherche, vous pouvez transmettre ce VC lors de l'initialisation de la propriété searchController.

EDIT: J'ai relu votre question et on dirait que j'ai oublié d'ajouter quelque chose d'important.

UITableViewController a un membre appelé tableView. Vous pouvez récupérer la vue de table du contrôleur, mais pour renseigner votre UITableView, vous n'avez pas besoin de la toucher. Vous ne pouvez pas utiliser la logique SearchControllerdirectementavec UITableView. Vous devez travailler avec le contrôleur pour y arriver. Utilisez les méthodes de délégué et de source de données UITableViewController pour mettre à jour votre interface utilisateur de table avec les résultats de votre recherche.

Veuillez lire la suite sur l’utilisation de UITableViewController, UITableViewDelegate et UITableViewDataSource afin de comprendre comment y parvenir.

67
Andy Ibanez

Dans le cas de quelqu'un qui panique comme moi, ce code pourrait aider

class ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate,UISearchResultsUpdating {

    @IBOutlet weak var tblView: UITableView!

    var tabledata = ["lucques","chickendijon","godaddy","Amazon","chris","ambata","bankofamerica","abelcine","AUTO + TRANSPORTATION","BILLS + UTILITIES","FOOD + DINING","HEALTH","AutoCare", "Auto Payment" , "Gas+Fuel","Electric Bill", "Internet/Television","Fast Foodd", "Gorceries" , "Restaurants","Gym Membership", "Health Insurance","auto","note-bullet","knife","heart"]

    var filteredTableData = [String]()
    var resultSearchController = UISearchController()

    override func viewDidLoad() {
        super.viewDidLoad()
        tblView.delegate = self
        tblView.dataSource = self
        self.resultSearchController = ({
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()
            controller.searchBar.barStyle = UIBarStyle.Black
            controller.searchBar.barTintColor = UIColor.whiteColor()
            controller.searchBar.backgroundColor = UIColor.clearColor()
            self.tblView.tableHeaderView = controller.searchBar
            return controller
        })()
        self.tblView.reloadData()
    }

     func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.resultSearchController.active {
           return self.filteredTableData.count
        }else{
            return self.tabledata.count
       }
    }
     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var section = indexPath.section
        var row = indexPath.row
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier:"addCategoryCell")
        cell.selectionStyle =  UITableViewCellSelectionStyle.None
        cell.backgroundColor = UIColor.clearColor()
        cell.contentView.backgroundColor = UIColor.clearColor()
        cell.textLabel?.textAlignment = NSTextAlignment.Left
        cell.textLabel?.textColor = UIColor.blackColor()
        cell.textLabel?.font = UIFont.systemFontOfSize(14.0)

        if self.resultSearchController.active {
              cell.textLabel?.text = filteredTableData[indexPath.row]
        } else {
                 cell.textLabel?.text = tabledata[indexPath.row]
        }
        return cell
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        filteredTableData.removeAll(keepCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
        let array = (tabledata as NSArray).filteredArrayUsingPredicate(searchPredicate)
        filteredTableData = array as! [String]
        self.tblView.reloadData()

    }
}
19
user4790024

Pour ceux qui recherchent un peu plus de contexte sur tous les aspects de la mise en œuvre, voici un tutoriel sur la mise en œuvre de UISearchController }

En plus de la réponse ci-dessus de Andy Ibanez , vous devez également ajouter du code à vos méthodes UITableViewDataSource pour afficher les résultats nouvellement filtrés dans la vue tableau. 

De plus, n'oubliez pas d'appeler tableView.reloadData() dans votre méthode updateSearchResults - UISearchController n'indique pas automatiquement à tableView de recharger ses données.

0
Bdebeez