web-dev-qa-db-fra.com

Créer par programme des vues dans IOS (Comment ça marche)?

Un peu d’arrière-plan: je vis les vidéos CS193P iTune et je suis resté bloqué sur la mission 3 pendant très longtemps. En gros, l’affectation vous demande de créer par programme une vue personnalisée pour afficher une forme à l’écran. En passant, je n'utilise aucun contrôleur de vue.

Je ne pouvais pas afficher ma vue avant d'avoir finalement fait glisser un objet View dans Interface Builder et de changer le nom de l'objet en ma classe de vue personnalisée. Ma question est donc la suivante: quand les gens disent de créer une vue par programme, disent-ils simplement de créer manuellement la classe, mais lorsque vous devez l’afficher, utilisez IB? Je ne peux pas m'empêcher de penser que j'ai mal compris quelque chose?

edit: laissez-moi être plus clair. Ma vue personnalisée a été initialisée avec un cadre de 0, 0, 200, 150 et drawRect est annulé pour dessiner un carré. Ma vue n'apparaît même pas si vous essayez de l'ajouter à la fenêtre principale de mon contrôleur:

    UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview:polygonView];

Cependant, si vous faites glisser une vue dans IB et changez la classe en ma classe de vue, elle s'affiche correctement.

Edit: Ajout de code. C'est la méthode awakeFromNib de mon contrôleur où la vue doit être dessinée.

    - (void)awakeFromNib {
    shape = [[PolygonShape alloc] initWithNumberOfSides:numberOfSidesLable.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12];
    polygonView = [[PolygonView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    polygonView.backgroundColor = [UIColor blackColor];
    [window addSubview:polygonView];
    [self updateInterface];  
}

Une partie de la méthode updateInterface de mon contrôleur:

- (void)updateInterface {
    [polygonView setPolygon:shape];
    [polygonView setNeedsDisplay];
...
}

PolygonView.h

#import <UIKit/UIKit.h>
#import "PolygonShape.h"

@interface PolygonView : UIView {
    IBOutlet PolygonShape *polygon; 
}

@property (readwrite, assign) PolygonShape *polygon;

- (void)drawRect:(CGRect)rect;
@end

PolygonView.m

#import "PolygonView.h"

@implementation PolygonView
@synthesize polygon;

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        nslog(@"initialized");
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
       CGRect bounds = [self bounds];

    [[UIColor grayColor] set];
    UIRectFill(bounds);

    CGRect square = CGRectMake(10, 10, 10, 100);
    [[UIColor blackColor] set];
    UIRectFill(square);

    [[UIColor redColor] set];
    UIRectFill(square);
    NSLog(@"drawRect called");
}
@end

PolygonView est en cours d'initialisation mais drawRect n'est pas appelé.

16
subject_x

Pour être encore plus spécifique à votre question, la syntaxe serait la suivante:

UIWindow* window = [UIApplication sharedApplication].keyWindow;

UIView *polygonView = [[UIView alloc] initWithFrame: CGRectMake ( 0, 0, 200, 150)];
//add code to customize, e.g. polygonView.backgroundColor = [UIColor blackColor];

[window addSubview:polygonView];
[polygonView release];

C'est un modèle que vous utiliserez non seulement pour cela, mais également pour les sous-vues. De plus, avec un grand nombre de modèles, le viewController est déjà configuré avec sa propre vue. Lorsque vous souhaitez créer une vue personnalisée, vous la créez comme ci-dessus, mais au lieu de la méthode ci-dessus, vous définissez la vue viewControllers sur la vue nouvellement créée, comme suit:

viewController.view = polygonView;

Bonne chance!

17
SushiGrass Jacob

C'est une vieille question, mais je ne suis pas sûr qu'il ait la réponse qu'il espérait - il semblerait qu'il soit confronté au même problème que celui dans lequel j'avais créé une sous-classe UIViewController, assommé une UIViewController dans une nib de constructeur d'interface, mais sans succès. Découvrez comment faire en sorte que les deux travaillent ensemble.

Si vous avez créé le nib séparément (ainsi, il n’a pas été créé pour vous le long de votre classe), vous devez alors vous rappeler de cliquer sur le contrôle UIViewController que vous avez placé dans le générateur d’interface, puis sur le troisième bouton d’onglet ('Personnaliser la classe'). '). Class sera la classe de base par défaut UIViewController etc. - ouvrez simplement cette liste déroulante et vous verrez une liste de toutes vos sous-classes personnalisées, sélectionnez-la et volla - vous avez lié votre élément personnalisé à l'interface.

J'espère que cela épargnera à quelqu'un les jours qu'il m'a fallu pour comprendre, j'ai trouvé des façons stupidement merveilleuses de contourner le problème jusqu'à ce que je réalise la solution simple.

4
RoyalFool

salut viens d'ajouter ce code, 

[window bringSubviewToFront:polygonView];

right after,
 [window addSubview:polygonView];
2
Saad Tasawar

Vous devez avoir une vue (ou une fenêtre) pour ajouter une sous-vue. La syntaxe normale est la suivante:

UIView *newView = [[UIView alloc] initWithFrame:mainView.bounds];
[mainView addSubview:newView];
[newView release];

Bien sûr, si vous avez un objet personnalisé qui hérite de UIView, utilisez-le plutôt que UIView. Lorsque vous démarrez un nouveau projet, créez une "application basée sur une vue", qui démarrera avec un contrôleur de vue avec une vue associée (accessible avec "CustomViewController.view", qui remplacerait "mainView" dans l'extrait de code. au dessus de).

Si vous souhaitez créer la vue par programme au démarrage de l'application, insérez le code dans la méthode "- (void) viewDidLoad" de votre contrôleur de vue.

2
Ned

Avez-vous défini la couleur de fond de votre vue sur quelque chose de différent?

Êtes-vous sûr que votre vue ne s'affiche pas ou est-ce simplement que vous ne pouvez pas la voir? Placez un NSLog dans la méthode drawRect: de votre vue (si vous utilisez une classe de vue personnalisée).

0
fzwo

Récemment, j'ai eu un problème très similaire et voici ce qui a fonctionné pour moi: au lieu de addSubview. Alors:

// Initialize myView and then
[window setRootViewController:myView];
// instead of [window addSubview:myView];
// the rest as normal...
[window makeKeyAndVisible];

Après cela, vous pouvez utiliser la méthode addSubview pour ajouter des vues supplémentaires.

0
Matjan

Quelque part dans votre classe de contrôleur actif, vous pouvez ajouter une vue personnalisée à la vue de niveau supérieur actuelle.

[ myCurrentTopView addSubview: myNewCustomView ];

Il est utile d’allouer et d’initialiser cette vue personnalisée en premier.

Ensuite, vous pouvez déclencher des dessins dans drawRect de cette vue personnalisée en effectuant un:

[ myNewCustomView setNeedsDisplay ];
0
hotpaw2

appel

[super drawRect];

avant votre code personnalisé dans drawRect: body.

0
DaddyM