UIView en escala de grises. Ver no ser networkingiseñado

Logré get una UIView en escala de grises agregando la siguiente vista en la parte superior:

@interface GreyscaleAllView : UIView @property (nonatomic, retain) UIView *underlyingView; @end @implementation GreyscaleAllView @synthesize underlyingView; - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); // draw the image [self.underlyingView.layer renderInContext:context]; // set the blend mode and draw rectangle on top of image CGContextSetBlendMode(context, kCGBlendModeColor); CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0); CGContextFillRect(context, rect); [super drawRect:rect]; } @end 

Funciona, pero el contenido no se actualiza a less que llame manualmente a setNeedsDisplay. (Puedo presionar un button UIB y la acción se dispara, pero nada cambia en apariencia) Para que se comporte como se esperaba, llamo a setNeedsDisplay 60 veces por segundo. ¿Qué estoy haciendo mal?

ACTUALIZAR:

El viewcontroller entra en la superposition con esto:

 - (void)viewDidLoad { [super viewDidLoad]; GreyscaleAllView *grey = [[[GreyscaleAllView alloc] initWithFrame:self.view.frame] autorelease]; grey.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; grey.userInteractionEnabled = NO; [self.view addSubview:grey]; } 

He agregado esto para las vistas subyacentes para volver a dibujar:

 @implementation GreyscaleAllView - (void)setup { self.userInteractionEnabled = FALSE; self.contentMode = UIViewContentModeRedraw; [self networkingrawAfter:1.0 / 60.0 repeat:YES]; } - (void)networkingrawAfter:(NSTimeInterval)time repeat:(BOOL)repeat { if(repeat) { // NOTE: retains self - should use a proxy when finished [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; } [self setNeedsDisplay]; } 

Lo que realmente desea es que se le solicite a la subvista que vuelva a dibujar cuando la vista principal se -setNeedsDisplay dibujar, en cuyo caso puede anular -setNeedsDisplay en la vista primaria y hacer que llame -setNeedsDisplay en GreyscaleAllView . Esto requiere la subclass UIView para la propiedad de view UIViewController .

es decir, implementa loadView en el controller y establece

 self.view = [[CustomView alloc] initWithFrame:frame]; 

donde CustomView anula setNeedsDisplay como se describe arriba:

 @implementation CustomView - (void)setNeedsDisplay { [grayView setNeedsDisplay]; // grayView is a pointer to your GreyscaleAllView [super setNeedsDisplay]; } @end 

Para completar, también debe hacer lo mismo para -setNeedsDisplayInRect: