iOS - Semi-transparent modal view controller

2019-02-02 05:23发布

I want to present a view controller with a slightly transparent background modally over the current view, such that the first view is slightly visible under the modal view.

I set the alpha value of the modal view controller and set the modalPresentationStyle to UIModalPresentationCurrentContext, as suggested in another post.

The result is that the view background is transparent when animating up, but when view controller is in place it changes to opaque black. It goes back to being transparent while animating the dismissal.

How can I get it to be transparent when active ?

I have tested in iOS 6 and 7. The code I am using follows:

MyModalViewController *viewController = [[MyModalViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navController setNavigationBarHidden:YES];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:NULL];

8条回答
可以哭但决不认输i
2楼-- · 2019-02-02 05:35

The reason that the BG view controllers disappear after a modal is shown is that the default transition in iOS 7 removes the BG view after animation completed. If you define your own transition and you set your BG view not to be removed (just changing its alpha) then you will have the transparent modal view.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-02 05:38

FYI: The syntax is now:

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
查看更多
【Aperson】
4楼-- · 2019-02-02 05:41

Same problem occured to me. I have solved it by looking at the following url about a custom alert controller. I managed to get it working even with a UINavigationController.

Swift 4

let viewController = UIViewController()
viewController.providesPresentationContextTransitionStyle = true
viewController.definesPresentationContext = true
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
DispatchQueue.main.async {
    self.navigationController?.present(viewController, animated: true, completion: nil)
}
查看更多
forever°为你锁心
5楼-- · 2019-02-02 05:45

My solution is this:

Create a custom transparent overlay UIView that comes over any view, navigationbar and tabbbar.

-In the navigation controller (or tabbar controller) that your view controller is embedded in I create a custom view with it's frame equal to the frame of the navigation controller's view.

-Then I set it offscreen by setting it's origin.y to navigationController.view.height

-Then I create 2 functions -(void)showOverlay and -(void)hideOverlay that animate the overlay view on and off screen:

- (void)hideOverlay{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;//helpView is my overlay
    frm.origin.y = self.offscreenOffset; //this is an Y offscreen usually self.view.height
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

- (void)showOverlay{

    [self.view bringSubviewToFront:self.helpView];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;
    frm.origin.y = self.onscreenOffset;
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

-In my view controller I can just call

[(MyCustomNavCtrl *)self.navigationController showOverlay];
[(MyCustomNavCtrl *)self.navigationController hideOverlay];

And that's about it.

查看更多
We Are One
6楼-- · 2019-02-02 05:46

iOS 8 added a new modal presentation style specifically for this purpose:

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

From the spec:

UIModalPresentationOverFullScreen

A view presentation style in which the presented view covers the screen. The views beneath the presented content are not removed from the view hierarchy when the presentation finishes. So if the presented view controller does not fill the screen with opaque content, the underlying content shows through.

查看更多
放荡不羁爱自由
7楼-- · 2019-02-02 05:48

Here is a solution.

Create your presenting view controller. Add a backView to this view controller's main view. Name this as backView.

In SecondViewController.m

-(void)viewDidLoad
{
    // Make the main view's background clear, the second view's background transparent.
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view addSubview:backView];
}

Now you have a view controller with half transparent background. You can add anything you want to the self.view , the rest will be half transparent.

After that, in FirstViewController.m

self.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:secondViewController animated:YES completion:nil];
查看更多
登录 后发表回答