Display clearColor UIViewController over UIViewCon

2019-01-02 18:57发布

I have a UIViewController view as a subview/modal on top of another UIViewController view, such as that the subview/modal should be transparent and whatever components is added to the subview should be visible. The problem is that I have is the subview shows black background instead to have clearColor. I'm trying to make UIView as a clearColor not black background. Does anybody know what is wrong with it? Any suggestion appreciated.

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];  

SecondViewController.m

- (void)viewDidLoad 
{
     [super viewDidLoad];
     self.view.opaque = YES;
     self.view.backgroundColor = [UIColor clearColor];
}

RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

NOTICE: If you are using a modalPresentationStyle property of navigationController:

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:

When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.

You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

16条回答
残风、尘缘若梦
2楼-- · 2019-01-02 19:48

RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

NOTICE: If you are using a modalPresentationStyle property of navigationController:

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:

When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.

You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

查看更多
无与为乐者.
3楼-- · 2019-01-02 19:50

I found the easiest way to get it to work on iOS7 and iOS8 is to add set the presentationStyle to UIModalPresentationOverCurrentContext on the modallyPresentedVC (ViewController which you want to present modally) because of iOS8:

[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

and UIModalPresentationCurrentContext on presentingVC (the controller which presents the modallyPresented) because of iOS7:

[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];

Because things are handled differently on iOS7 and iOS8. Of course you don't have to set the navigationController properties if you are not using one. Hope that helps.

查看更多
千与千寻千般痛.
4楼-- · 2019-01-02 19:52

iOS 7 solution with custom segue:

CustomSegue.h
#import <UIKit/UIKit.h>

    @interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

    @end



CustomSegue.m
#import "CustomSegue.h"

@implementation CustomSegue

-(void)perform {

    UIViewController* destViewController = (UIViewController*)[self destinationViewController];
    destViewController.view.backgroundColor = [UIColor clearColor];
    [destViewController setTransitioningDelegate:self];
    destViewController.modalPresentationStyle = UIModalPresentationCustom;
    [[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}


//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.25f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

    UIView *inView = [transitionContext containerView];
    UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [inView addSubview:toVC.view];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];

    [UIView animateWithDuration:0.25f
                     animations:^{

                         [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
                     }
                     completion:^(BOOL finished) {
                         [transitionContext completeTransition:YES];
                     }];
}


//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    //I will fix it later.
    //    AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
    //    controller.isPresenting = NO;
    //    return controller;
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

@end

Solution based on hightech code.

查看更多
大哥的爱人
5楼-- · 2019-01-02 19:52

For iOS 7 and only by using Interface Builder it can be accomplished by setting the Presentation to "Over Current Context" on all the view controllers involved in the modal presentation. Even for navigation controllers.

For instance, set it on all these view controllers:

NavController -> RootViewController -> ModalViewController

enter image description here

查看更多
何处买醉
6楼-- · 2019-01-02 19:55

Just use "self.modalPresentationStyle = UIModalPresentationCurrentContext;", in presenting view

Will work fine :)

查看更多
余欢
7楼-- · 2019-01-02 19:57

Swift 3 & iOS10 solution :

//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)
查看更多
登录 后发表回答