如何创建半透明模式 UIViewController?

Posted

技术标签:

【中文标题】如何创建半透明模式 UIViewController?【英文标题】:How can I create a translucent modal UIViewController? 【发布时间】:2009-09-30 16:37:18 【问题描述】:

我想创建一个可重用的 UIViewController 子类,它可以显示为模式视图控制器,而不是任何其他视图控制器。这个可重用的 VC 需要做的第一件事就是弹出一个 UIActionSheet。为了做到这一点,我在我的 VC 中创建了一个默认(空白)视图来显示操作表。

但是,这看起来很糟糕,因为当模态 vc 弹出时,父 vc 被隐藏了。因此,操作表看起来像是漂浮在空白背景上。如果操作表可以显示在原始(父)vc 之上会更好。

有没有办法做到这一点?简单地获取父 vc 的视图并从中为 UIActionSheet 设置动画是否安全?

【问题讨论】:

遇到同样的问题..有什么解决办法吗?? 【参考方案1】:

在您的模态视图动画化后,它的大小将调整为与其父视图相同。你可以做的是在你的 viewDidAppear: 中,为 parentController 的视图拍照,然后在你自己视图的子视图列表的后面插入一个包含父视图的 UIImageView:

#pragma mark -
#pragma mark Sneaky Background Image
- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];

    // grab an image of our parent view
    UIView *parentView = self.parentViewController.view;

    // For ios 5 you need to use presentingViewController:
    // UIView *parentView = self.presentingViewController.view;

    UIGraphicsBeginImageContext(parentView.bounds.size);
    [parentView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *parentViewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // insert an image view with a picture of the parent view at the back of our view's subview stack...
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    imageView.image = parentViewImage;
    [self.view insertSubview:imageView atIndex:0];
    [imageView release];


- (void)viewWillDisappear:(BOOL)animated 
    [super viewWillDisappear:animated];

    // remove our image view containing a picture of the parent view at the back of our view's subview stack...
    [[self.view.subviews objectAtIndex:0] removeFromSuperview];

【讨论】:

对于 iOS 5,您需要使用 presentingViewController 而不是 parentViewController。我更新了您的答案以包括在内。 这通常效果很好,但是当我尝试它时,我在父视图图像的顶部得到一个 20 px 的间隙,由状态栏引起(我猜)。有什么更正的建议吗? 更新:我已经通过将图像上下文向上翻译 20 像素来进行修复,但我仍然很好奇为什么我必须在似乎没有其他人的情况下这样做? 听起来好像您使用的屏幕空间与某些不同。例如,您可能没有在顶部显示您的应用的状态栏,而其他人则可能。 @Mac 您可能需要将模态视图控制器的wantsFullScreenLayout 属性设置为YES。【参考方案2】:

您可以通过在父视图中插入视图来简单地将其显示在父视图控制器上。

类似这样的:

PseudoModalVC *vc = ...//initialization
vc.view.backgroundColor = [UIColor clearColor]; // like in previous comment, although you can do this in Interface Builder
vc.view.center = CGPointMake(160, -vc.view.bounds.size.height/2);
[parentVC.view addSubView:vc.view];

// animation for pop up from screen bottom
[UIView beginAnimation:nil context:nil];
vc.view.center = CGPointMake(160, vc.view.bounds.size.height/2);
[UIView commitAnimation];

【讨论】:

如果您这样做,您还需要在显示的视图控制器中对诸如“viewWillAppear”之类的方法进行所有适当的调用。 UINavigationController 和模态系统通常会为您处理这个问题。【参考方案3】:

是的。将其添加到当前视图控制器的视图中(或作为窗口的子视图)并像 Valerii 所说的那样在屏幕上对其进行动画处理。

要使用动画删除它,请执行以下操作(我假设模态视图为 320 x 460,它会从屏幕上滑下):

- (void)dismissModal

    // animate off-screen
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    [UIView setAnimationDuration:0.50];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.view.frame = CGRectMake( 0, 480, 320, 460 );

    [UIView commitAnimations];


- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

    // don't remove until animation is complete. otherwise, the view will simply disappear
    [self.view removeFromSuperview];

【讨论】:

以上是关于如何创建半透明模式 UIViewController?的主要内容,如果未能解决你的问题,请参考以下文章

如何在图像上制作半透明颜色?

分组 UITableView 的半透明 UITableViewCell?

翻译11 Unity 透明渲染

易语言如何在画板中添加一个半透明的图片

创建内部带有透明孔的小部件

在半透明框架/面板/组件上重新绘制。