2009-05-06 17 views
11

J'ai une structure comme celui-ci ....iphone - UITableViewController d'accès de UITableViewCell

UITableViewController -> UITableViewCell -> UIView 

J'ai besoin UIView d'accéder à une table de hachage (NSMutableDictionary) dans le UITableViewController

est-il un moyen d'accès le ViewController simplement à partir de ViewCell (en utilisant [ViewCell surclassement] ne fonctionnera évidemment pas) .... Dois-je descendre à travers l'AppDelegate en utilisant [[UIApplication sharedApplication] delegate]?

Merci!

Répondre

7

Je maintiens habituellement une référence faible de mon UIView à mon UIViewController si je besoin d'un, le plus souvent en créant un quelque chose de méthode comme ceci:

-(MyView*)initWithController:(CardCreatorViewController*) aController andFrame:(CGRect)aFrame 
{ 
    if (self = [super initWithFrame:aFrame]) 
    { 
     controller = aController; 
     // more initialisation here 
    } 

    return self; 
} 

Vous pouvez également utiliser un modèle de délégué si vous voulez un plus découplées Solution. J'ai tendance à penser que c'est trop pour une vue et son contrôleur, mais je l'utiliserais avec un système de contrôleurs et de sous-contrôleurs.

4

Étant donné que UITableViewCell est quelque part dans la hiérarchie de vue, vous pouvez accéder à votre vue racine en récupérant view.superview jusqu'à ce que vous l'obteniez. Si vous ne souhaitez pas ajouter de propriétés à votre vue, vous pouvez accéder à son contrôleur via la propriété nextResponder de la vue. Vous devrez le lancer à n'importe quelle classe dont vous avez besoin, bien sûr, et ce n'est peut-être pas l'utilisation la plus propre de la propriété. C'est un hack rapide-n-sale pour y arriver. Si vous cherchez quelque chose que vous pouvez montrer à vos enfants, je viserais à passer par le délégué de votre application, ou si votre contrôleur de vue se trouve être un singleton, il suffit d'implémenter le motif de conception singleton et d'y accéder via cette.

27

Cela devrait faire l'affaire:

UITableView *tv = (UITableView *) self.superview.superview; 
UITableViewController *vc = (UITableViewController *) tv.dataSource; 
+6

J'utilise iOS 5.0 et cela ne fonctionne pas dans mon projet actuel, self.superview.superview est un UIView et non un UITableView ("[UIView dataSource]: selecognized selector"). – Max

+3

@Max Rien dans la documentation ne garantit que les cellules de vue de table seront deux sous-vues à partir des vues de table, donc cette réponse repose sur un comportement non documenté. Ce n'est pas surprenant que ce soit cassé. – Tommy

+0

Vous devez utiliser ceci: UITableView * tv = (UITableView *) self.superview; –

4

Quelques modifications de Kare Morstol réponse:

La hiérarchie des tableviewcell est dans iOS 5.0 (ma version de test)

cell.superview = tableview 
cell.superview.superview = UIViewControllerWrapperView 

Ainsi, utilisez cell.superview pour obtenir tableview. Et la tableview et tableviewController a une relation de délégué, dataSource par défaut.
Vous pouvez obtenir la référence tableviewController par tableview.delegate ou tableview.dataSource.

UITableView *tableView = cell.superview; 
UITableViewController *tableViewController = tableView.delegate; // or tableView.dataSource` 
7

Vous pouvez créer une catégorie pour cela:

@implementation UITableViewCell (FindTableViewController) 

- (id<UITableViewDataSource>)tableViewController 
{ 
    UIView *view = self; 
    while (!(view == nil || [view isKindOfClass:[UITableView class]])) { 
     view = view.superview; 
    } 

    return ((UITableView *)view).dataSource; 
} 

@end 

alors vous pouvez simplement accéder à self.tableViewController de la cellule elle-même (en supposant que vous avez inclus cette catégorie). Vous devrez peut-être le lancer dans la classe tho de votre contrôleur de table.