5

次のビューを上に追加することで、グレースケールの 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

動作しますが、setNeedsDisplay を手動で呼び出さない限り、コンテンツは更新されません。(UIButton を押すとアクションが実行されますが、外観は何も変わりません) 期待どおりに動作させるために、毎秒 60 回 setNeedsDisplay を呼び出します。私は何を間違っていますか?

アップデート:

ビューコントローラーは、次のようにオーバーレイビューを初期化します。

- (void)viewDidLoad
{
    [super viewDidLoad];

    GreyscaleAllView *grey = [[[GreyscaleAllView alloc] initWithFrame:self.view.frame] autorelease];
    grey.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    grey.userInteractionEnabled = NO;    
    [self.view addSubview:grey];
}

下にあるビューを再描画するためにこれを追加しました。

@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];
}
4

1 に答える 1

1

本当に必要なのは、親ビューが再描画されたときにのみサブビューに再描画するように指示することです。その場合-setNeedsDisplay、親ビューでオーバーライドして-setNeedsDisplayGreyscaleAllView. UIViewControllerこれには、のプロパティのUIView をサブクラス化する必要がありviewます。

loadViewつまり、コントローラーに実装して設定します

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

CustomViewsetNeedsDisplayは上記のようにオーバーライドします。

@implementation CustomView

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

@end

完全を期すために、次の場合も同じことを行う必要があります-setNeedsDisplayInRect:

于 2012-10-31T23:28:59.577 に答える