2011-03-09 18 views
5

Tengo la siguiente configuración de jerarquía de vista en mi programa.¿Por qué el cursor parpadeante en el campo de texto hace que se llame a drawRect?

Window 
+ContentView (Subview of Window) 
++MyCustomView (Subview of ContentView) 
++MyCustomOpaqueView (Subview of ContentView) 
+++TextField (Subview of MyCustomOpaqueView) 

Cuando el usuario hace clic en el campo de texto, el cursor dentro de él comienza a parpadear. En cada parpadeo se llama a drawRect en MyCustomView. No es un gran problema, pero me pregunto por qué?

En MyCustomOpaqueView implemento Isopaque como tal,

- (BOOL)isOpaque {return YES;} 

pensé que esto sería bloquear mensajes dirigidos a drawRect en MyCustomView si el NSRect pasó a drawRect está completamente oscurecida por una visión opaca, pero cuando el cursor parpadea MyCustomView todavía se envía el mensaje drawRect con un NSRect completamente detrás de una vista opaca.

¿Me falta un concepto clave o es esto una peculiaridad del cursor parpadeante?


+0

+1: ¡Buena investigación! Como ha resuelto esto, considere editar y poner la solución en una respuesta para que la pregunta no aparezca en "Sin respuesta". –

+0

Hizo lo que recomienda. – Tobias

Respuesta

2

Resolviendo esta respuesta por recomendación de Josh Caswell.


Pregunté sobre esto en una reunión de CocoaHeads. Recibí una sugerencia para ver el HitTest de NSView. Por lo tanto en mis vistas personalizadas, que hizo caso omiso de la función hittest del NSView así:

- (NSView*) hitTest:(NSPoint)aPoint { 
    static int depth = 1; 
    NSLog([NSString stringWithFormat:@"%%%dd ENTER %%@ - hitTest", depth], 
      depth, [[self class] description]); 
    depth++; 
    NSView *hitView = [super hitTest:aPoint]; 
    depth--; 
    NSLog([NSString stringWithFormat:@"%%%dd EXIT %%@ - hitTest: %%@", depth], 
      depth, [[self class] description], [[hitView class] description]); 
    return hitView; 
} 

A continuación se muestra la salida:

MyCustomView es subvista de contentView.
MyOpaqueCustomView (OCV) es una subvista de contentView.

1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
MyCustomView - Dirty Rect: {{49, 189}, {127, 28} //!!Focus Ring Around Text Field 
OCV - Dirty Rect: : {{49, 189}, {127, 28}} 
testTextField isOpaque? Yes 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 ENTER MyCustomView - hitTest 
1 EXIT MyCustomView - hitTest: MyCustomView 
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} //!!EVERY BLINK 
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} 
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} 
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} 

MyCustomView es vista secundaria de la contentView.
MyOpaqueCustomView (OCV) es una subvista de MyCustomView.

1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 EXIT MyCustomView - hitTest: NSTextField 
1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 EXIT MyCustomView - hitTest: NSTextField 
1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
1 EXIT MyCustomView - hitTest: NSTextView 
OCV - Dirty Rect: : {{49, 189}, {127, 28}} //!!FOCUS RING 
testTextField isOpaque? Yes 
1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
1 EXIT MyCustomView - hitTest: NSTextView 
1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextView 
1 EXIT MyCustomView - hitTest: NSTextView 
1 ENTER MyCustomView - hitTest 
1 ENTER OCV - hitTest 
1 EXIT OCV - hitTest: NSTextField 
1 EXIT MyCustomView - hitTest: NSTextField 
//!!BLINKING HERE - But no dirtyRects. 

Así que parece que la respuesta a hitTest define qué vistas obtendrán vuelve a dibujar.

Cuestiones relacionadas