简体   繁体   中英

How can I create a translucent modal UIViewController?

I'd like to create a reusable UIViewController subclass that can be shown as a modal view controller over any other view controller. One of the first things this reusable VC needs to do is pop up a UIActionSheet. In order to do this, I create a default (blank) view in my VC to show the action sheet from.

However, this looks bad because, when the modal vc pops up, the parent vc is hidden. Thus it looks like the action sheet is floating over a blank background. It'd be better if the action sheet could appear to pop over the original (parent) vc.

Is there a way to achieve this? Is it safe to simply grab the parent vc's view and animate the UIActionSheet from that?

After your modal view animates in, it is resized to be equal in size to its parent view. What you can do is inside your viewDidAppear:, take a picture of the parentController's view, then insert a UIImageView containing the picture of the parent at the back of your own view's list of subviews:

#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];
}

You can simply show it over your parent view controller by inserting view in a parent view.

Something like this:

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];

Yep. Add it to the current view controller's view (or as a subview of the window) and animate it on-screen like Valerii said.

To remove it with an animation, do this (I'm assuming the modal view is 320 x 460 and it will slide down off the screen):

- (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];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM