模态 VC 和旋转的自定义背景
Posted
技术标签:
【中文标题】模态 VC 和旋转的自定义背景【英文标题】:A custom background for a modal VC and rotation 【发布时间】:2014-03-24 18:44:34 【问题描述】:我为 iPad 上的模态视图控制器实现了自定义(模糊)背景。我是这样做的:在展示的 VC 的viewWillShow:
中,我拍摄展示的 VC 视图的快照图像,将其模糊,然后在展示的 VC 顶部添加一个 UIImage 视图。这很好用。
但是,当我在显示模式时旋转设备时,模糊图像与它所代表的视图控制器不同步。图像被拉伸以填满屏幕,但视图控制器不会以相同的方式调整其视图的大小。因此,当模态消失并且模糊消失时,过渡看起来很糟糕。
我尝试在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;
【问题讨论】:
能否请您发布实际代码。 @MaxK 发布了代码。 为什么要给self.presentingViewController
添加子视图?如果我理解正确,您想在模态图中显示 presentingViewController
的模糊图像 - 那么您应该这样做 [self.view addSubView:_backgroundBlurView]
@MaxK 我只想更改 iPad 上模态(非全屏)视图的默认外观。默认行为是使背景半透明。我为此添加了一个模糊。模态视图控制器不受影响。模糊图像需要位于模态下方,因此我将其添加到呈现的 VC 中。我希望这是有道理的!
能否请您将图片保存成照片并使用以下代码UIImage *img = [STSUtils imageByBlurringView:self.presentingViewController.view]; UIImageWriteToSavedPhotosAlbum(img, nil, nil, NULL);
并在此处发布。我们需要定位一个错误——无论是截屏还是显示不正确。尝试使用和不使用模态控制器的两种方向。
【参考方案1】:
我编写了一个简单的示例,该示例从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];
来自苹果文档:
afterUpdates 一个布尔值,指示快照是否 应在合并最近的更改后呈现。 如果要在视图中呈现快照,请指定值 NO 层次结构的当前状态,可能不包括最近的更改。
所以您截取的屏幕截图不包含视图中的最新更改。
【讨论】:
我想你在这里回答了一个稍微不同的问题 :) 我不打算对演示者 VC 进行快照并在模态 VC 中显示它。我希望用它自己的快照图像覆盖演示者 VC,但模糊。我将尝试绘制图表并将其添加到我的问题中。 对不起,第一次没有得到你想要的。但现在我愿意,会尽力帮助你。 我已经发布了一个示例项目来说明这个问题。尝试(1)打开模态,然后(2)旋转屏幕,(3)然后关闭模态。您会看到 (2) 中的模糊背景与 (3) 中的实际背景不匹配。 为什么这是公认的答案?是否有展示重绘作品的示例项目? 我会将 didRotateFromInterfaceOrientation 替换为 viewWillLayoutSubviews - 效果更好,但仍不能以最佳方式处理旋转。以上是关于模态 VC 和旋转的自定义背景的主要内容,如果未能解决你的问题,请参考以下文章