2011-01-27 14 views
15

Un poco de historia: estoy repasando los videos CS193P iTune y me quedé atrapado en la tarea 3 por mucho tiempo. Básicamente, la tarea le pide que cree programáticamente una vista personalizada para mostrar una forma en la pantalla. No estoy usando ningún controlador de vista por cierto.Creación mediante programación de vistas en IOS (¿cómo funciona)?

No pude ver mi vista hasta que finalmente arrastré un objeto View en Interface Builder y cambié el nombre del objeto a mi clase de vista personalizada. Entonces, mi pregunta es cuando las personas dicen que creen una vista de forma programática. ¿Acaban de decir que crean la clase manualmente pero cuando necesitan mostrarla usan IB? No puedo evitar sentirme como si hubiera entendido mal algo?

editar: déjame ser más claro. Mi vista personalizada se ha inicializado con un marco de 0, 0, 200, 150 y DrawRect se reemplaza para dibujar un cuadrado. Mi punto de vista ni siquiera aparece si intento de añadir a la ventana principal dentro de mi controlador:

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

Sin embargo, si el uso de arrastrar una vista en IB y cambiar la clase a mi clase de vista, se muestra bien.

Editar: Se ha añadido algún código. Este es el método awakeFromNib de mi controlador donde debe dibujarse la vista.

- (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]; 
} 

Parte del método updateInterface de mi controlador:

- (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 

se está inicializando El polygonView pero el drawRect ISN no se está hablando re.

+0

¿Dónde se está creando la keyWindow? Si no está cargando un archivo nib (no está claro en su pregunta si lo es o no), entonces tendría que crear la ventana primero antes de agregar su subvista. – jlehr

+0

Se está creando en la clase AppDelegate. ¿Esto significa que tengo que Importar mi clase polygonView allí y crearla allí? –

+0

Curiosamente, si pongo la inicialización y la adición de mi vista a la ventana en mi método updateInterface, funciona, pero solo después de hacer clic en un botón que llama al método. Parece que el código no está siendo procesos en awakeFromNib. ¿Algunas ideas? –

Respuesta

16

Para ser aún más específica a su pregunta, la sintaxis sería

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]; 

Ésta es una patrón que utilizará no solo para esto, sino para las subvistas posteriores. Además, otra nota es que con muchas de las plantillas, viewController ya está configurado con su propia vista. Cuando se quiere hacer una vista personalizada, lo crea como el anterior pero en lugar del método anterior configura los viewControllers ver a la vista recién creada de esta manera:

viewController.view = polygonView; 

Buena suerte!

+0

Debo estar haciendo algo mal entonces. Lo tengo exactamente como lo has escrito y mi vista no se muestra. –

+0

Hmmm ... ¿Qué sucede si comenta drawRect o específicamente lo llama en initWithFrame con [self drawRect] ;? –

+0

No pasa nada diferente si no anulo drawRect. Si llamo drawRect desde el método initWithFrame obtengo un error de excepción: "reason: '- [PolygonView drawRect]: selector no reconocido enviado a la instancia 0x4b58c70'" ​​ –

2

Necesita tener una vista (o ventana) para agregar una subvista. La sintaxis normal es de esta manera:

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

Por supuesto, si usted tiene un objeto personalizado que hereda de UIView, utilizaría que en lugar de UIView. Cuando inicie un nuevo proyecto, cree una "Aplicación basada en vista", que lo iniciará con un controlador de vista con una vista asociada (que se puede acceder con "CustomViewController.view", que reemplazaría a "mainView" en el fragmento de código encima).

Si desea crear la vista mediante programación cuando se inicia la aplicación, coloque el código en el método "- (void) viewDidLoad" de su controlador de vista.

+0

Sé que un controlador View sería el camino a seguir, pero en esta asignación en particular solo hay una clase de modelo, una clase de controlador y la clase de vista personalizada. ¿Estás diciendo que tendría que agregar mi objeto de vista a la ventana principal? ¿Cómo y dónde haría eso? –

0

En algún lugar de su clase de controlador activo, puede agregar una vista personalizada a la vista de nivel superior actual.

[ myCurrentTopView addSubview: myNewCustomView ]; 

Ayuda a asignar e inicializar esta vista personalizada primero.

A continuación, puede desencadenar alguna de dibujo en drawRect de esta vista personalizada haciendo una:

[ myNewCustomView setNeedsDisplay ]; 
+0

Mi topview actual es la ventana principal. La ventana principal no es un objeto en mi clase de controlador, así que ¿cómo puedo configurar mi vista como una subvista ([window addSubView: ...] no funciona). –

0

¿Ha establecido el color de fondo de su vista a algo distinguible?

¿Está seguro de que su vista no se muestra, o simplemente es que no puede verla? Ponga un NSLog en el método drawRect: de su vista (si usa una clase de vista personalizada).

+0

Sí, traté de establecer mi color de fondo inicial en negro solo para ver si puedo ver aparecer una vista blanca o gris, que no lo hizo. También puse un mensaje NSLog en drawRect y iniWithFrame que tampoco se mostró en la consola. No creo que mi vista se esté inicializando aunque tengo PolygonView = [polygonView initWithFrame: CGRectMake (0, 10, 320, 480)]; en el método awakeFromNib de mi controlador. –

+0

Retiro eso sobre la vista que no se inicializa. Lo es y aparece el mensaje NSLog en iniWithFrame. Es solo el mensaje NSLog en drawRect que no se muestra. Puedo ver que mis datos en mi modelo se pasan a mi vista correctamente. Simplemente no puedo entender por qué la ventana no mostrará mi vista. –

+0

Tal vez un poco más de código nos ayude a analizar la situación en ese momento. – fzwo

4

Esta es una vieja pregunta, pero no estoy seguro de que haya obtenido la respuesta que esperaba - parece que se encontró con el mismo problema que yo, creé una subclase UIViewController, conecté un UIViewController en un compilador de interfaz, pero entonces no pude entender cómo hacer que los dos trabajen el uno con el otro.

Si fabricó el plumín por separado (por lo que no estaba hecho para usted junto con su clase), debe recordar hacer clic en el Controlador UIView que colocó en el constructor de interfaz y luego en el botón Propiedades. ('Clase personalizada'). El Class será la clase base predeterminada UIViewController etc. - solo abra esta lista desplegable y verá una lista de todas sus subclases personalizadas, selecciónela y volla; ha vinculado su elemento personalizado a la interfaz.

Espero que le ahorre a alguien los días que tardé en descubrirlo, encontré algunas maneras estúpidamente maravillosas de resolverlo hasta que me di cuenta de la solución simple.

0

Tuve un problema muy similar recientemente y esto es lo que funcionó para mí: Parece que cuando comienzas con una 'aplicación vacía' en Xcode 4.3.2 tienes que establecer tu vista como la vista raíz de tu ventana principal usando el Método setRootViewController en lugar de addSubview. Entonces:

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

Después de eso, puede usar el método addSubview para agregar vistas adicionales.

2

alta sólo tiene que añadir este código,

[window bringSubviewToFront:polygonView]; 

right after, 
[window addSubview:polygonView]; 
+1

Es una mala práctica ... – Resty

0

llamada

[super drawRect]; 

antes de que su código personalizado en drawRect: cuerpo.

Cuestiones relacionadas