web-dev-qa-db-fra.com

Recharger un seul en-tête de section dans UITableView

J'utilise une cellule personnalisée comme en-tête de section dans ma UITableView. Dans cette cellule, il y a trois boutons. Si vous cliquez sur l'un des boutons dans la cellule de cette section, il convient de recharger cette cellule de section personnalisée uniquement, pas les lignes. Est-ce possible?

J'utilisais le code suivant pour recharger cette cellule: 

tableViewHome.reloadSections([1], with: UITableViewRowAnimation.none)

Cela cache ma cellule de section et déforme tout mon tableau.

METTRE À JOUR

J'utilise UITableView et le code suivant que j'utilise:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let cellHeader = tableViewHome.dequeueReusableCell(withIdentifier: "header") as! HeaderTableViewCell

        cellHeader.filter1btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)
        cellHeader.filter2Btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)
        cellHeader.filter3btn.addTarget(self, action: #selector(filterBtnAction(_:)), for: .touchUpInside)


        return cellHeader
    }


    @IBAction func filterBtnAction(_ sender: UIButton) {

        print(sender.tag)

        tableViewHome.reloadSections([1], with: UITableViewRowAnimation.none)



    }
5
Abhishek Mitra

Je ne sais pas trop ce qui se passe ici, mais cela ressemble à un concept UITableView intéressant à expliquer ici: 

UITableView a son propre concept de cellule, implémenté en tant que UITableViewCell , et son propre concept d’en-tête/pied de page, implémenté en tant que UITableViewHeaderFooterView

En fonction de laquelle de ces deux personnes vous voulez dire, il y a quelques choses que vous pouvez faire pour obtenir l'effet souhaité: 

L'approche UITableViewCell:

Si vous utilisez une UITableViewCell comme première ligne d'une section pour agir comme un "en-tête" et que vous souhaitez simplement recharger cette ligne à l'exclusion du reste de la section, vous pouvez appeler yourTableViewInstance.reloadRows(at:with:)(Documentation Apple ) Cette méthode utilise un tableau de IndexPaths et un style d'animation. Vous pouvez transmettre le chemin indexPath de celui que vous voulez recharger.

L'approche UITableViewHeaderFooterView:

Si vous utilisez une UITableViewHeaderFooterView appropriée, vous devez vous assurer de fournir la vue appropriée lors du rechargement de la section. Zack Shapiro décrit les étapes à suivre dans cette réponse :

  1. Créez une classe qui est une sous-classe de UITableViewHeaderFooterView.
  2. Enregistrez-le avec votre instance UITableView.
  3. Ensuite, dans viewForHeaderInSection, vous faites let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! YourHeaderViewSubclass

La dernière chose qu'il souligne est la suivante:

Ce qui est trompeur, c'est que la fonction appelle un retour de UIView? quand elle a vraiment besoin de dequeuedReusableHeaderFooterView ou reloadData le fera disparaître.

Cela dépend de laquelle de ces deux chemins d’implémentation vous prenez, mais cela devrait être assez d’informations pour vous diriger dans la bonne direction.

Modifier:

En fonction du code que vous avez ajouté, il semblerait que vous appeliez yourTableViewInstance.dequeueReusableCell(withIdentifier:for:) au lieu de yourTableViewInstance.dequeueReusableHeaderFooterView(withIdentifier:) à l'intérieur de viewForHeaderInSection.

Vous devez avoir une sous-classe de UITableViewHeaderFooterView et l'appeler ensuite correctement. Créez cette nouvelle sous-classe, puis changez ceci:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let cellHeader = tableViewHome.dequeueReusableCell(withIdentifier: "header") as! HeaderTableViewCell

   // ...

pour ça:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let cellHeader = tableViewHome.dequeueReusableHeaderFooterView(withIdentifier: "header") as! HeaderTableView

   // ...

Vous devez suivre deux étapes ici:

  1. Créez une nouvelle classe, sous-classe UITableViewHeaderFooterView au lieu de UITableViewCell.
  2. Ensuite, utilisez la classe appropriée comme indiqué ci-dessus.
4
Moshe

Oui, ça l'est. 

Disons qu'il s'agit de la mise en oeuvre de votre méthode: 

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let customCell = .... as! YourCustomCell 
    customCell.someLabel.text = "Some Data"
    //... filling your curstom cell
    return customCell
}

Vous pouvez le changer de cette façon 

func updateHeaderView(headerView:YourCustomCell, section: Int) {
    customCell.someLabel.text = "Some Data"
    //... filling your curstom cell  
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let customCell = .... as! YourCustomCell 
    self.updateHeaderView(customCell, section)
    return customCell
}

Et appelez à nouveau self.updateHeaderView(customCell, section) quand vous le souhaitez, par exemple. 

func buttonClicked() {
   let customCell = self.tableView.headerView(forSection: 0) as! YourCustomCell
   self.updateHeaderView(customCell, 0)
}
1
arturdev

Ce que j'ai fait et travaille très correctement, veuillez suivre la réponse donnée:

Swift 3.1

Étape 1:

Premièrement, j'ai pris une view xib, conçue en fonction de mes besoins et inscrite dans la classe requise. 

Deuxièmement, la sous-classe class HeaderView: UITableViewHeaderFooterView de UITableViewHeaderFooterView 

Comme l'image suivante: 

 enter image description here

Dans la classe requise (ici, homeclass), j'ai enregistré mon fichier xib pour ma tableview.

override func viewDidLoad() {
        super.viewDidLoad()
        tableViewHome.register(UINib(nibName: "HeaderView", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderView")
}

Étape 2:

Ensuite, dans mon cours obligatoire, j'ai suivi les cours suivants:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let cellHeader = tableViewHome.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! HeaderView
        cellHeader.filterAction(cellHeader.filter1Btn)


        return cellHeader
    }

Et cela a commencé à fonctionner selon mes besoins, plus tard, j'ai ajouté un délégué personnalisé pour plus d'actions dans ma classe, mais en sous-affichage, cela fonctionne maintenant. 

1
Abhishek Mitra