1

最近、UIView に半透明効果を追加する方法について同様の質問をしたところ、良い回答が得られました。

ただし、処理に多くの CPU パワーを使用したため、回答の背後にあるいくつかのアイデアを使用しましたが、はるかに効率的な GPUImage を使用してフィルタリングを行いました。

静的な画面ではうまく機能しますがUIImageView、アニメーションで背景の画像を変更したいです。ただしUIView、遷移中に背景をサンプリングするように設定すると、遷移が無視され、アニメーションが開始される前に新しい画像が表示されるようです。
関連するコードは次のとおりです (さらに必要な場合はお問い合わせください!)。

カスタムUIViewUIImageView背景を含むスーパービュー:

//The Transition
[contentView setScheduled:YES]; //Starts the sampling every 0.2 seconds

//bg is the UIImageView and contentView is the 'translucent' UIView subclass
[UIView transitionWithView:bg duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    [bg setImage:newImage];
}completion:^(BOOL finished){
    [contentView setScheduled:NO];
}];

次に、UIView サブクラスで:

- (UIImage *)snapshotOfSuperview:(UIView *)superview
{
CGFloat scale = 0.5;
if (([UIScreen mainScreen].scale > 1 || self.contentMode == UIViewContentModeScaleAspectFill))
{
    CGFloat blockSize = 12.0f/5;
    scale = blockSize/MAX(blockSize * 2, floor(self.blurRadius));
}
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -self.frame.origin.x, -self.frame.origin.y);
self.hidden=YES; //Don't take a snapshot of the view
[superview.layer renderInContext:context];
self.hidden=NO;
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}

-(void)updateViewBG{
UIImage *superviewImage = [self snapshotOfSuperview:self.superview];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    GPUImageGaussianBlurFilter* filter = [[GPUImageGaussianBlurFilter alloc] init];
    filter.blurSize = 0.8f;
    UIImage* newBG = [self applyTint:self.tintColour image:[filter imageByFilteringImage:superviewImage]];

    dispatch_async(dispatch_get_main_queue(), ^{
        self.layer.contents = (id)newBG.CGImage;
        self.layer.contentsScale = newBG.scale;
    });
});
}

-(UIImage*)applyTint:(UIColor*)colour image:(UIImage*)inImage{
UIImage *newImage;
if (colour) {
    UIGraphicsBeginImageContext(inImage.size);

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect area = CGRectMake(0, 0, inImage.size.width, inImage.size.height);

    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -area.size.height);
    CGContextSaveGState(ctx);
    CGContextClipToMask(ctx, area, inImage.CGImage);
    [colour set];
    CGContextFillRect(ctx, area);
    CGContextRestoreGState(ctx);
    CGContextSetBlendMode(ctx, kCGBlendModeLighten);
    CGContextDrawImage(ctx, area, inImage.CGImage);
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}else{
    newImage = inImage;
}
return newImage;
}

-(void)displayLayer:(CALayer *)layer{
[self updateViewBG];
}

背景をアニメーションに追従させるにはどうすればよいですか?

4

1 に答える 1