模态VC和旋转的自定义背景

时间:2014-03-24 18:44:35

标签: ios objective-c ios7 uiviewcontroller

我在iPad上为模态视图控制器实现了自定义(模糊)背景。以下是我的工作方式:在提供的VC viewWillShow:中,我拍摄了VC视图的快照图像,模糊了它,并在其上添加了一个UIImage视图。介绍VC。这很有效。

但是,当我在模式显示时旋转设备时,模糊图像与它所代表的视图控制器不同步。图像被拉伸以填满屏幕,但视图控制器不会以相同的方式调整其视图的大小。因此,当模态被解除并且模糊消失时,过渡看起来很糟糕。

我已尝试在didRotateFromInterfaceOrientation:中拍摄另一张快照,并替换模糊图像,但这并不起作用。

关于如何解决这个问题的任何建议?

更新:a sample project

我的代码(在模态视图控制器中):

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self drawBackgroundBlurView];
}    

- (void)drawBackgroundBlurView
{
    if(_blurModalBackground) {

        [_backgroundBlurView removeFromSuperview];

        CGRect backgroundFrame = self.presentingViewController.view.bounds;

        _backgroundBlurView = [[UIImageView alloc] initWithFrame:backgroundFrame];
        _backgroundBlurView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        [_backgroundBlurView setImage:[STSUtils imageByBlurringView:self.presentingViewController.view]];

        [self.presentingViewController.view addSubview:_backgroundBlurView];
    }
}

实用程序代码

+ (UIImage *)imageByBlurringView:(UIView *)view
{
    UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];

    BOOL isPortrait = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]));

    CGRect frame;
    if(isPortrait) {
        frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.height, view.frame.size.width);
    }
    else {
        frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
    }

    UIGraphicsBeginImageContextWithOptions(frame.size, NO, window.screen.scale);

    [view drawViewHierarchyInRect:frame afterScreenUpdates:NO];

    // Get the snapshot
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();

    // Apply blur
    UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
    UIImage *blurredSnapshotImage = [snapshotImage applyBlurWithRadius:8
                                                             tintColor:tintColor
                                                 saturationDeltaFactor:1.8
                                                             maskImage:nil];

    UIGraphicsEndImageContext();

    return blurredSnapshotImage;
}

1 个答案:

答案 0 :(得分:2)

我编写了一个简单的示例,它从presentingViewController获取屏幕截图并将其设置为背景图像。这是我的模态视图控制器的实现。它运行良好(在viewWillAppear上都可以正确处理旋转)。您还可以发布STSUtils代码吗?

#import "ScreenshoterViewController.h"

@interface ScreenshoterViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

- (IBAction)buttonBackPressed;

@end

@implementation ScreenshoterViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self updateImage];
}

- (void)updateImage
{
    UIGraphicsBeginImageContext(self.view.bounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self.presentingViewController.view.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.imageView.image = img;
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self updateImage];
}

- (IBAction)buttonBackPressed {
    [self dismissViewControllerAnimated:YES
                             completion:NULL];
}
@end

<强>更新

在你的utils代码中,只需替换这个

[view drawViewHierarchyInRect:frame afterScreenUpdates:NO];

用这个

[view drawViewHierarchyInRect:frame afterScreenUpdates:YES];

来自apple docs:

  

afterUpdates一个布尔值,指示是否为快照   应在最近的变更合并后呈现。   如果要在视图中呈现快照,请指定值NO   层次结构的当前状态,可能不包括最近的更改。

所以你拍的截图没有包含视图中的最新变化。