J'ai le suivant
J'ai utilisé un NIB (un fichier .xib) pour la cellule, qui utilise une classe CustomCell. Cette classe de cellule personnalisée gère IBAction pour une touche sur le bouton de la cellule. Je voudrais faire référence au ViewController et à certaines de ses variables. Comment suis-je censé le faire (accéder à ViewController)?
Merci!
Je ne créerais pas ce type de dépendance entre la cellule et le contrôleur de vue - cela rend l'architecture plus complexe et la cellule non réutilisable.
Je vous suggère d'utiliser le modèle de délégation, ce qui peut sembler un peu compliqué - bien que vous l'utilisiez déjà (UITableViewDelegate
est un exemple typique):
MyCellProtocol
avec une méthode didTapCell
, en acceptant un UITableViewCell
et/ou certaines données personnalisées que vous souhaitez transmettre au contrôleur de vueweak var cellDelegate: MyCellProtocol?
didTapXXX
ou didSelectRowAtIndexPath
de votre cellule, appelez self.cellDelegate?.didTapCell()
, en passant les paramètres attendusMyCellProtocol
cellForRowAtIndexPath
de votre contrôleur de vue, lors de la création/retrait de la cellule, définissez sa propriété cellDelegate
sur self
À ce stade, lorsqu'un tap est effectué dans votre cellule, la méthode didTapCell
du contrôleur de vue est appelée, et à partir de là, vous pouvez faire tout ce que vous devez réaliser.
Le point clé est le suivant: plutôt que de faire en sorte que la cellule gère le tap/selection de cellule, informez le contrôleur de vue et laissez-le faire le travail.
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
À l'intérieur de ta cellule
if let myViewController = parentViewController as? MyViewController {
print(myViewController.title)
}
Je ne pense pas que vous devriez faire cela et vous faites probablement quelque chose de mal, mais si vous en avez vraiment besoin, alors il suffit d'avoir une propriété dans votre classe CustomCell
.
var viewController : UIViewController
puis lorsque vous créez la cellule dans cellForRowAtIndexPath
définissez la propriété
cell.viewController = self
après cela, vous pouvez facilement accéder au contrôleur de vue depuis le code de la cellule:
self.viewController.doSomething()
Mais encore une fois, à mon avis, vous devriez reconcevoir votre code. La cellule ne doit pas se soucier du contrôleur. Il ne devrait se soucier que de s'afficher et de rien d'autre
ajouter une extension
extension UITableViewCell {
var viewControllerForTableView : UIViewController?{
return ((self.superview as? UITableView)?.delegate as? UIViewController)
}
}
maintenant downCast comme ci-dessous
if let viewController = self.viewControllerForTableView as? AnyController{
print(viewController.variable)
}
.
Le meilleur moyen est de mettre en œuvre la délégation. Votre délégué informera le contrôleur de vue du clic sur le bouton. Et, à son tour, votre contrôleur de vue (qui conforme le protocole pour le délégué ci-dessus) gérera la tâche que vous souhaitez effectuer lors d'un événement de clic. (Des didacticiels sur les modèles de délégation sont disponibles en ligne. Vous pouvez les parcourir si vous voulez savoir comment effectuer la délégation).
Lisez les autres commentaires sur le fait de vouloir vraiment utiliser une approche alternative avant d'essayer, mais l'utilisation de cette extension vous permettra d'accéder aux dataSource
et delegate
qui devraient tous deux être les UITableViewController
extension UITableViewCell {
var tableView:UITableView? {
get {
for var view = self.superview ; view != nil ; view = view!.superview {
if view! is UITableView {
return (view! as UITableView)
}
}
return nil
}
}
var tableViewDataSource:UITableViewDataSource? {
get {
return self.tableView?.dataSource
}
}
var tableViewDelegate:UITableViewDelegate? {
get {
return self.tableView?.delegate
}
}
}