UIView在灰度.查看未重绘

jal*_*aas 5 uiview grayscale ios

我设法通过在顶部添加以下视图来获得灰度级的UIView:

@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
Run Code Online (Sandbox Code Playgroud)

它工作正常,但除非我手动调用setNeedsDisplay,否则内容不会更新.(我可以按下UIButton并触发动作,但外观没有任何变化)因此,为了表现得像预期的那样,我每秒调用setNeedsDisplay 60次.我究竟做错了什么?

更新:

viewcontroller在overlayview中使用:

- (void)viewDidLoad
{
    [super viewDidLoad];

    GreyscaleAllView *grey = [[[GreyscaleAllView alloc] initWithFrame:self.view.frame] autorelease];
    grey.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    grey.userInteractionEnabled = NO;    
    [self.view addSubview:grey];
}
Run Code Online (Sandbox Code Playgroud)

我已经为底层视图添加了这个重绘:

@implementation GreyscaleAllView

- (void)setup {

    self.userInteractionEnabled = FALSE;
    self.contentMode = UIViewContentModeRedraw;

    [self redrawAfter:1.0 / 60.0 repeat:YES];

}

- (void)redrawAfter:(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];
}
Run Code Online (Sandbox Code Playgroud)

yfr*_*cis 1

您真正想要的是仅在父视图重绘时告诉子视图重绘,在这种情况下,您可以-setNeedsDisplay在父视图中覆盖并使其-setNeedsDisplay调用GreyscaleAllView. 这需要为您的属性创建 UIView 的子UIViewControllerview

loadView即在控制器中实现,并设置

self.view = [[CustomView alloc] initWithFrame:frame];
Run Code Online (Sandbox Code Playgroud)

其中 CustomView 重写setNeedsDisplay如上所述:

@implementation CustomView

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

@end
Run Code Online (Sandbox Code Playgroud)

为了完整起见,您还应该对-setNeedsDisplayInRect: