2009-10-11 10 views
10

Por lo tanto, tengo una subclase UIView personalizada que permite el dibujo de bordes redondeados. La cosa se dibuja a la perfección, sin embargo, el fondo siempre llena todos los límites, a pesar de estar en primer lugar. El borde también dibuja sobre el fondo rectangular, a pesar de que dibujo el borde en drawRect: antes del fondo. Así que eliminé todo el contenido de drawRect :, que ahora está prácticamente vacío, ¡sin embargo, se dibuja el fondo!La subclase UIView dibuja un fondo a pesar del draw completamente vacíoRect: - ¿por qué?

¿Alguien tiene una explicación para esto? Configuré backgroundColor en Interface Builder. ¡Gracias!

+0

Es probable que haya un problema con el código de dibujo. ¿Puedes publicarlo para que podamos echar un vistazo? Mi suposición es que en algún lugar estás dibujando de una manera que o bien ignora los valores alfa o dibuja algo opaco sobre lo que pensabas que sacaste. Además, solo para asegurarse de que, cuando configura el 'backgroundColor', ¿tiene el alfa establecido apropiadamente? –

+0

Bueno, puedo publicar mi drawRect :, pero como he dicho, está completamente vacío:

 - (void) drawRect:(CGRect)rect { } 
El alfa se establece en IB, y se dibuja en cualquier color que establezca, con cualquier alfa. Supongo que debe haber algo en el interior, sin embargo, no hay una nueva supervista y ninguna subvista que pueda estar dibujando el fondo. También el color de fondo de la capa de la vista es nulo. – Pascal

Respuesta

20

Lo siento por este monólogo. :)

El hecho es que la capa de UIView aparentemente dibuja el fondo, que es independiente de drawRect:. Es por esto que no puede deshacerse del fondo anulando drawRect:.

Usted puede anular - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx y hacer el sorteo capa de lo que quiera, o anular - (void) setBackgroundColor:(UIColor *)newColor y no asigna Newcolor a backgroundColor, pero a su propio Ivar, como myBackgroundColor. A continuación, puede usar myBackgroundColor en drawRect; dibujar el fondo como quieras


Anulación setBackgroundColor:

definir una variable de instancia para mantener su color de fondo, por ejemplo, myBackgroundColor. En sus métodos de arranque, establecer el color de fondo real para ser el clearColor:

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    if ((self = [super init...])) { 
     [super setBackgroundColor:[UIColor clearColor]]; 
    } 
    return self; 
} 

Anulación:

- (void) setBackgroundColor:(UIColor *)newColor 
{ 
    if (newColor != myBackgroundColor) { 
     [myBackgroundColor release]; 
     myBackgroundColor = [newColor retain]; 
    } 
} 

A continuación, utilice myBackgroundColor en su drawRect: método. De esta forma, puede usar el color asignado desde Interface Builder (o Xcode4) en su código.

0

Esto es fácilmente reproducible:

crear una nueva vista basado en la aplicación iPhone. Cree una subclase UIView y deje el método drawRect: completamente vacío. En Interface Builder, arrastre un UIView en la vista principal, asígnele un color de fondo y configure la clase de la vista en su subclase. Guarde, cree y ejecute, y vea, la vista muestra el color de fondo.

He eludido este comportamiento anulando setBackgroundColor: y asignando el color a mi propio ivar, siempre dejando la propiedad backgroundColor nil. Esto funciona, sin embargo, todavía me pregunto por qué esto funciona de esta manera.

6

Dudo en sugerir esto porque no quiero ofenderte, pero ¿has puesto opaco a NO?

+1

Sin ofender, la pregunta es realmente buena: Sí, opaco se estableció en NO. :) – Pascal

+0

A veces es así de simple ... ¡Gracias! –

8

Aquí es una solución fácil:

self.backgroundColor = [UIColor clearColor]; 
+0

Sí, eso es lo que se logra sobrescribiendo setBackgroundColor :. Me preguntaba más por qué se dibujaba algo, a pesar de drawRect: estar vacío. La respuesta fue que el fondo se dibuja en drawLayer: inContext :. – Pascal

0

Debe establecer

clearsContextBeforeDrawing = NO 

Es así de simple.

Desde el UIView Reference Docs

Vaya. Yo malentendí la pregunta. El OP (póster original) quiere que su control personalizado admita la propiedad estándar "backgroundColor" (por ejemplo, establecido por el diseñador de GUI), pero NO quiere que el sistema pintee ese color. El OP quiere pintar el bg él mismo para que pueda redondear las esquinas.

En ese caso, la publicación sobre la anulación del dibujo a nivel de capa es correcta.

La solución que publiqué evitará que el sistema de IU limpie tu memoria intermedia antes de dibujar. Cuando no se ha definido bg, si se establece clearsContextBeforeDrawing, iOS borrará el búfer de la vista, configurando todos los píxeles en negro transparente. Hacer esto para una vista de pantalla completa lleva unos 5 ms en un iPad3, por lo que no es gratis (lo que empuja a 2048x1536 píxeles nunca lo es). Para comparar, dibujar un mapa de bits a pantalla completa (usando kCGBlendModeCopy para forzar el blitting) lleva ~ 25ms (usando cuarzo, no GPU).

+0

Esto no impide que se dibuje backgroundColor; al menos no soy mi prueba rápida. – Pascal

+0

¿Qué sucede si desarma backgroundColor? –

+0

Entonces funciona, por lo que elegí anular 'setBackgroundColor:' para no poner color en super y guardar el color de fondo en mi propio ivar. De esta forma, el color de fondo asignado en el constructor de interfaces se usa en mi costumbre 'drawRect:' y no tengo que manejar esto en el código. :) – Pascal

Cuestiones relacionadas