2009-07-25 7 views
0

Je me demandais juste si cette approche semble être une bonne pratique pour les applications avec beaucoup de vues personnalisées, pour les graphiques PNG imbriqués et les animations qui peuvent changer en fonction de l'interaction de l'utilisateur. J'ai créé une classe BaseView qui s'étend UIViewPratique UIView et UIViewController pour l'héritage

@interface BaseView : UIView { 
    @protected 
    BaseViewController *controller; 
} 

@property (retain) BaseViewController *controller; 

@end 

et une classe de commande correspondant, qui est l'emplacement principal que je suis en train de code pour manipuler la vue

@interface BaseViewController : UIViewController { 
    @protected 
    CGRect drawArea; 
} 

- (void) drawArea:(CGRect) _drawArea; 
- (CGRect) drawArea; 
- (void) linkSubviewController: (BaseViewController *) _subviewController; 

@end 

où « drawArea » est le CGRect utilisé pour passez à la vue en tant que cadre.

« linkSubviewController » vous permet d'imbriquer un contrôleur et vue comme suit:

- (void) linkSubviewController: (BaseViewController *) _subviewController { 
    [self.view addSubview:[_subviewController view]]; 
} 

En outre, je paire en couches une autre personnalisée appelée « ImageView » et « ImageViewController » qui s'étendent BaseView mais aussi stocker un UIImage et un x, y, w, h

dans les méthodes de dessin "drawRect" sur les vues que je peux vérifier pour voir si des vars dans les vars self.controller ont été modifiés, ou assigner des images, par exemple:

UIImage *image = [(ImageViewController *)self.controller image]; 
CGContextDrawImage(...) etc 

J'écris la plupart des méthodes de loadview quelque chose comme ça

- (void)loadView { 
    ImageView *v = [[ImageView new] initWithFrame:drawArea]; 
    v.controller = self; 
    self.view = v; 
} 

La base de routine « initWithFrame » contient

self.backgroundColor = [UIColor clearColor]; 
    self.opaque = NO; 

Je peux charger une variété d'images avec un fond transparent, sans avoir à assigner que chaque temps.

J'ai été en mesure d'utiliser ce code dans toute mon application et il semble qu'il soit facile d'écrire une classe de premier niveau qui assemble la mise en page des éléments personnalisés. Pour les animations, je les ai mises dans les contrôleurs et j'ai manipulé self.view.layer.

Fondamentalement, je suis à la recherche des commentaires, je suis nouveau avec Objective-C et l'iPhone SDK

Répondre

4

Il y a plusieurs problèmes ici:

  1. [[Classname new] init...] est à l'aide de l'utilisation incorrecte de new. En utilisant new est court pour [[Classname alloc] init] de sorte que vous appelez effectivement init deux fois.
  2. Les vues ne devraient pas vraiment avoir besoin de savoir qui les contrôle.
  3. Votre vue est retain en utilisant le contrôleur, et puisque UIViewController conserve sa vue, vous avez un cycle de rétention et aucun ne sera jamais complètement release d.

Si vous voulez que ce type de comportement (dans lequel une vue peut déléguer son dessin à un parent), essayez de créer un protocole DrawDelegate, ont vos contrôleurs mettre en œuvre ce protocole, et dans votre sous-classe de vue un non-maintien drawDelegate propriété:

@protocol DrawDelegate 
- (void) drawArea:(CGRect)rect; 
@end 

@interface BaseView : UIView { 
    id<DrawDelegate> drawDelegate; 
} 
@property (assign) id<DrawDelegate> drawDelegate; 
@end 
+0

Y a-t-il une raison spécifique d'utiliser [Class new] sur [[Class alloc] init]? Autre que l'initWith étendu évident et whatnot. – Sneakyness

+1

@Sneakyness + new est une convention qui meurt lentement. Il est inflexible par rapport à + alloc-init, car + new * doit * appeler + alloc-init, alors qu'utiliser + alloc signifie que vous pouvez utiliser n'importe quelle méthode -init ou -initWith ... que vous aimez. –

+0

Merci beaucoup! Le + nouveau est une erreur évidente, merci. Je vais essayer l'approche de la délégation. Mon objectif principal ici est de conserver les informations d'état dans les contrôleurs et de les redessiner en fonction d'un changement dans le contrôleur, et mes classes d'applications peuvent exécuter les contrôleurs. En outre, une partie du plan était de pouvoir envoyer des événements tactiles à un contrôleur. Il est clair qu'il faut retravailler mais je pense que la délégation va aider. – Michael

Questions connexes