Charger une vue depuis un nib

yodarkyodark Membre
14:13 modifié dans API AppKit #1
Bonjour,

Question simple mais qui me fait tourner en rond depuis un petit moment

Comment faire pour charger correctement une vue depuis un nib ?

j'ai testé


marche parfait par contre

UIView * view3 = [[UIView alloc] initWithNibName:@SecondView bundle:nil];


[self addSubview: view1];

fait planter mon application pourquoi ?

Question subsidiaire si j'ai attaché un view controller au nib le controller sera chargé avec la vue automatiquement ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    14:13 modifié #2
    J'imagine que tu as bien mis view3 partout (ou view1 partout, au choix), parce que dans ton code tu as mixé les deux variables...
    Sinon, peut-être une piste ici ?
  • Philippe49Philippe49 Membre
    octobre 2008 modifié #3
    dans 1222878044:


    UIView * view3 = [[UIView alloc] initWithNibName:@SecondView bundle:nil];


    [self addSubview: view1];

    fait planter mon application pourquoi ?

    Question subsidiaire si j'ai attaché un view controller au nib le controller sera chargé avec la vue automatiquement ?




    La méthode standard c'est de créer/initialiser/retenir le view controller attaché au nib,  puis d'ajouter la vue
        viewController=[[UIViewController alloc] initWithNibName:@SecondView bundle:nil];
        [theView addSubview:viewController.view];
    où theView est la vue qui va recevoir la nouvelle vue comme sous-vue.
    A priori theView et viewController sont des variables de self , qui lui est un contrôleur.


  • yodarkyodark Membre
    14:13 modifié #4

    J'ai

    #import "RadarViewController.h"

    RadarViewController * mRadarViewController ;
    [...]
    @property (nonatomic, retain) RadarViewController * mRadarViewController;
    [...]
    @synthesize mRadarviewController;
    [...]

    mRadarviewController = [UIViewController initWithNibName:@RadarView bundle:nil];
    [self addSubview:mRadarviewController.view];


    J'ai une erreur UIViewController may not respond to +initWithNibName

    Comment ça se fait?
  • Philippe49Philippe49 Membre
    14:13 modifié #5
    Oui j'ai oublié le alloc dans mon code.
    Ceci dit si le view controller que tu veux créer est de la classe RadarViewController, il faut naturellement adapter en
    mRadarviewController = [[RadarViewController alloc] initWithNibName:@RadarView bundle:nil];

  • yodarkyodark Membre
    14:13 modifié #6
    Excellent merci beacoup ca marche !

    Encore une petite question : Le contrôleur de l'ancienne vue continue à  répondre ( j'ai une fonction on click sur la vue1 qui appelle la vue RadarView. Le problème est qu'une fois RadarView chargée le programme continue a appeler cet vue quand je clic dans la fenêtre)
  • Philippe49Philippe49 Membre
    14:13 modifié #7
    Il faut envoyer le message removeFromSuperview à  la vue précédente
  • 14:13 modifié #8
    Personnellement, voilà  comment je fais :

    Il faut savoir aussi que j'ai un .nib avec une vue uniquement (et ma classe "MyViewController" évidemment)

    "MyViewController" descend de NSObject.

    Voici le MyViewController.m :
    <br />+ (id) controller<br />{<br />&nbsp; &nbsp; return [[[self alloc] init] autorelease];<br />}<br /><br />- (id) init<br />{<br />&nbsp; &nbsp; if ((self = [super init]) != nil)<br />&nbsp; &nbsp; {<br />		NSArray*&nbsp; &nbsp; topLevelObjs = nil;<br /><br />		topLevelObjs = [[NSBundle mainBundle] loadNibNamed:@&quot;Restore&quot; owner:self options:nil];<br />		if (topLevelObjs == nil)<br />		{<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self release];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self = nil;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return self;<br />}<br /><br />- (void) dealloc<br />{<br />&nbsp; &nbsp; [subview release];<br />&nbsp; &nbsp; [super dealloc];<br />}<br /><br />- (UIView *) view<br />{<br />&nbsp; &nbsp; return subview;<br />}<br />
    


    Et voilà  comment charger la vue principale de "MyViewController" dans une autre class (comme le MainMenu.nib) :

    AppController.m :
    <br />- (IBAction)addView:(id)sender<br />{<br />&nbsp; &nbsp;[[[myMainView subviews] objectAtIndex:0] removeFromSuperview]; // On supprime la vue actuelle<br /><br />&nbsp; &nbsp; MyViewController* viewController = [MyViewController controller];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp;[myMainView addSubview:[viewController view]];<br />}<br />
    


    Et tout ça sur iPhone donc pas de soucis niveau compatibilité.
  • yodarkyodark Membre
    14:13 modifié #9
    j'ai pas tout a fait compris ce que tu fais Eaglelouk tu cree une vue au top level avec le nib Restore ?

    Comment fait on pour rappeller la supervue ? (la vue précédente?) Ca consomme plus de mémoire d'empiler les vues ainsi?

  • octobre 2008 modifié #10
    dans 1222946558:

    j'ai pas tout a fait compris ce que tu fais Eaglelouk tu cree une vue au top level avec le nib Restore ?

    Comment fait on pour rappeller la supervue ? (la vue précédente?) Ca consomme plus de mémoire d'empiler les vues ainsi?




    Elle est automatiquement supprimée cette vue précédente dans mon code. tu remarqueras le : [[[myMainView subviews] objectAtIndex:0] removeFromSuperview];

    Et oui, il vaut mieux ne pas empiler les 2 vues. Tout simplement parce d'un côté ça rend moche (même si sur iPhone ya un background blanc, mais sur une NSView c'est transparent, ducoup ça superpose les éléments des deux vues), et d'un autre côté tu as 2 vues chargée dans ton programme = plus de consommation de mémoire, alors que tu peux en avoir qu'une seule de chargée à  la place.

    Pour résumé le code, imagine que tu as un AppController qui gère ton programme niveau code principale. Tu désires appeler les préférences de ton application.
    Là  tu vas créer un "Preferences.nib" et un "PreferencesController". Le nib contiendra une UIView, et le PreferencesController descendra de NSObject. Dans le .m tu mets le premier morceau de code que je t'ai filé. ça va charger ton Preferences.nib et tu vas pouvoir faire joujou avec. (Ne pas oublier aussi d'affecter "PreferencesController" comme classe à  ton NSObject (cube bleu) de Preferences.nib).

    Dans ton MainMenu.nib, tu as "AppController" qui est instancié, et tu as ta fenêtre principale. Cette fenêtre contient une UIView qui prend toute la place de la fenêtre (ou moins, à  ta guise quoi). Tu n'oublies pas de définir ta UIView en IBOutlet.

    Dans le AppController.m, sur l'action "showPreferences:(id)sender" il te suffira de mettre la deuxième partie de mon code qui va se charger, en premier lieu, de supprimer la vue actuelle de contenue dans la vue principale, elle-même contenue dans la fenêtre principale de MainMenu.xib. Cela veut dire qu'au préalable tu auras affecté une sous-vue à  ta vue principale au démarrage de l'appli, dans le awakeFromNib par exemple (mais il est préférable d'utiliser la méthode délégate qui est proposée pour l'iPhone lorsque la fenêtre principale est chargée).
    Ensuite, le code va se charger d'initialisé un nouveau "PreferencesController" qui va lui-même charger le Preferences.xib.
    Grâce à  la méthode "controller" (qui contient le [[[self alloc] init] autorelease];), la classe + le fichier interface .xib des préférences seront automatiquement relâchés.
    Pour éviter donc tout plantage, il est préférable de soit stocker ton "nouveau NIB" dans une Array (utile si tu dois en gérer plusieurs en même temps), soit simplement rajouter "id currentNib;" dans le .h de AppController.

    Pour éviter tout plantage je t'invite donc à  changer le 2ème code par :
    <br /> [[[myMainView subviews] objectAtIndex:0] removeFromSuperview]; // On supprime la vue actuelle<br />&nbsp; &nbsp; [currentNib release];<br />&nbsp; &nbsp; currentNib = [MyViewController controller];<br />&nbsp; &nbsp; [currentNib retain];<br />&nbsp; &nbsp;[myMainView addSubview:[currentNib view]];<br />
    



    Edit : je vais te joindre un projet iPhone qui te montreras la voie à  suivre. Je te prépare ça.

    Edit 2 : Projet iPhone joint dans le post :) (Je l'ai fait en 2 minutes donc heu.. au moins j'espère que tu comprendras le principe).
  • Philippe49Philippe49 Membre
    14:13 modifié #11
    dans 1223067035:

    Elle est automatiquement supprimée cette vue précédente dans mon code. tu remarqueras le : [[[myMainView subviews] objectAtIndex:0] removeFromSuperview];

    Moi je préfèrerais un
        [firstViewController.view removefromSuperview];
        currentViewController=secondViewController;
    en décidant ensuite si je "release" le firstViewController si nécessaire



    dans 1223067035:

    Là  tu vas créer un "Preferences.nib" et un "PreferencesController". Le nib contiendra une UIView, et le PreferencesController descendra de NSObject

    Pourquoi le PreferencesController ne serait pas un UIViewController , relié au File's owner du nib créé ?

  • 14:13 modifié #12
    dans 1223067948:

    dans 1223067035:

    Elle est automatiquement supprimée cette vue précédente dans mon code. tu remarqueras le : [[[myMainView subviews] objectAtIndex:0] removeFromSuperview];

    Moi je préfèrerais un
        [firstViewController.view removefromSuperview];
        currentViewController=secondViewController;
    en décidant ensuite si je "release" le firstViewController si nécessaire



    dans 1223067035:

    Là  tu vas créer un "Preferences.nib" et un "PreferencesController". Le nib contiendra une UIView, et le PreferencesController descendra de NSObject

    Pourquoi le PreferencesController ne serait pas un UIViewController , relié au File's owner du nib créé ?




    Chacun sa méthode, mais sur iPhone je débute et moi tous ces controller ça m'énerve  ;D ;D Pour l'instant je me plonge pas plus que ça sur l'iPhone, je prend plutôt des vacances avant la rentrée.
  • Philippe49Philippe49 Membre
    14:13 modifié #13
    dans 1223068034:

    sur iPhone je débute et moi tous ces controller ça m'énerve  ;D ;D Pour l'instant je me plonge pas plus que ça sur l'iPhone, je prend plutôt des vacances avant la rentrée.

    Oui, moi aussi je m'y suis mis il y a 3-4 semaines et je suis bien occupé par ailleurs par mon boulot. J'ai l'impression que l'esprit n'est pas complètement le même que sous Cocoa, beaucoup plus standardisé, et laissant moins de champ à  l'imagination.

    C'est vrai que c'est la fête aux controller : Pour l'exemple SimpleDrillDown de gestion d'une table view, on a le droit à  un contrôleur pour l'appli, un pour la table view principale, un pour le data, un pour la table view de second niveau !  ;D ;D 
    Bon , quand même le controller de la table view principale s'autorise à  être datasource et delegate  ! :)
  • 14:13 modifié #14
    dans 1223069162:

    dans 1223068034:

    sur iPhone je débute et moi tous ces controller ça m'énerve  ;D ;D Pour l'instant je me plonge pas plus que ça sur l'iPhone, je prend plutôt des vacances avant la rentrée.

    Oui, moi aussi je m'y suis mis il y a 3-4 semaines et je suis bien occupé par ailleurs par mon boulot. J'ai l'impression que l'esprit n'est pas complètement le même que sous Cocoa, beaucoup plus standardisé, et laissant moins de champ à  l'imagination.

    C'est vrai que c'est la fête aux controller : Pour l'exemple SimpleDrillDown de gestion d'une table view, on a le droit à  un contrôleur pour l'appli, un pour la table view principale, un pour le data, un pour la table view de second niveau !  ;D ;D   
    Bon , quand même le controller de la table view principale s'autorise à  être datasource et delegate  ! :)


    Je suis d'accord avec toi, c'est un peu différent de l'esprit Cocoa. Dommage qu'on ait autant de controller, j'aime pas trop ça  ;D
Connectez-vous ou Inscrivez-vous pour répondre.