iOS:具有透明背景的Modal ViewController

Mic*_*ael 175 objective-c modalviewcontroller presentmodalviewcontroller ios

我试图以模糊方式呈现视图控制器,具有透明背景.我的目标是让呈现和呈现的视图控制器视图同时显示.问题是,当呈现动画结束时,呈现视图控制器的视图消失.

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以将视图添加为子视图,但出于某种原因我想避免使用此解决方案.我该怎么办呢?

Jef*_* C. 183

对于那些试图让它在iOS 8中工作的人来说,"Apple认可的"显示透明模态视图控制器的方法是通过设置modalPresentationStyle 当前的ed控制器来实现 UIModalPresentationOverCurrentContext.

这可以在代码中完成,也可以通过在故事板中设置segue的属性来完成.

从UIViewController文档:

UIModalPresentationOverCurrentContext

一种演示样式,其中内容仅显示在父视图控制器的内容上.演示文稿完成后,不会从视图层次结构中删除所显示内容下方的视图.因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来.

在弹出框中显示视图控制器时,仅当过渡样式为UIModalTransitionStyleCoverVertical时才支持此演示样式.尝试使用不同的过渡样式会触发异常.但是,如果父视图控制器不在弹出框中,则可以使用其他过渡样式(部分卷曲过渡除外).

适用于iOS 8.0及更高版本.

https://developer.apple.com/documentation/uikit/uiviewcontroller

来自WWDC 2014的"在iOS 8中查看控制器进展"视频详细介绍了这一点.

注意:

  • 务必为您呈现的视图控制器提供清晰的背景颜色,以免它实际上是透明的!
  • 你必须呈现之前设置它, presentViewController中设置这个参数viewDidLoad不会有任何影响

  • 注意 - 您需要设置的目标**modalPresentationStyle**已更改.例如,在iOS 7中,为了使其工作,我需要将试图打开模态的视图控制器的**modalPresentationStyle**设置为**UIModalPresentationCurrentContext**.但是,为了让它在iOS8中工作,我需要将模态视图的**modalPresentationStyle**设置为**UIModalPresentationOverCurrentContext**. (32认同)
  • 在iOS 8+上,我不得不从UINavigationController呈现一个模态,所以从孩子那里呈现并没有提供我需要的东西.相反,`sourceVC`是`self.navigationController`.此外,只有在将目标演示文稿样式设置为自定义后,我才能看透它.`[sourceVC setModalPresentationStyle:UIModalPresentationCurrentContext];`,`[targetVC setModalPresentationStyle:UIModalPresentationCustom];`希望它会帮助某人. (2认同)

小智 102

在iOS 8.0及更高版本中,可以通过将属性modalPresentationStyle设置为UIModalPresentationOverCurrentContext完成.

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:presentedController animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

请参见图像附加

  • 这是我可以开展工作的唯一解决方案.也很简单.只需在模态segue之前将其添加到您的演示VC中. (5认同)

S.P*_*.P. 94

以下代码仅适用于iPad.

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];
Run Code Online (Sandbox Code Playgroud)

我会添加一个子视图.

这是一个非常好的讨论.具体看一下评论.不仅是答案.

模态视图

如果我是你,我就不会这样做.我会添加一个子视图并执行它.它似乎让我更好地控制事物.

编辑:

正如Paul Linsay所提到的,因为iOS 8所需要的只是UIModalPresentationOverFullScreen呈现ViewController的modalPresentationStyle.这也包括navigationBar和tabBar按钮.

  • 它*可以在iOS 7和iPhone上工作,你必须在*presenter*视图控制器上指定`modalPresentationStyle = UIModalPresentationCurrentContext`,而不是在*present*中指定. (18认同)
  • 是的它可以工作,但只有你在视图层次结构的**更高的**`ViewController`上设置它.(例如,`NavigationController`或幻灯片菜单视图控制器的实例). (6认同)
  • 因为iOS 8所需要的只是UIModalPresentationOverFullScreen,用于呈现ViewController的modalPresentationStyle. (5认同)
  • 奇怪的是,在我的情况下,它仅在将模态样式设置为"UIModalPresentationCustom"之后才有效,并且只有在它设置在`presentViewController`之前而不是在`viewDidLoad`之前. (4认同)

mal*_*lex 42

此代码在iOS6和iOS7下的iPhone上运行正常:

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您会错过幻灯片动画.要保留动画,您仍然可以使用以下"非优雅"扩展名:

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];
Run Code Online (Sandbox Code Playgroud)

如果我们的presentationV位于UINavigationController或UITabbarController内部,则需要使用该控制器作为presentationVC进行操作.

此外,在iOS7中,您可以实现自定义过渡动画应用UIViewControllerTransitioningDelegate协议.当然,在这种情况下,您可以获得透明背景

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>
Run Code Online (Sandbox Code Playgroud)

首先,在介绍之前你必须设置 modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;
Run Code Online (Sandbox Code Playgroud)

然后你必须实现两种协议方法

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}
Run Code Online (Sandbox Code Playgroud)

最后一件事是在CustomAnimatedTransitioning课堂上定义自定义过渡

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这在iOS7上不起作用:我一直有黑色背景. (11认同)
  • 确认这是有效的.*注意*如果你的viewController在navigationController中,那么确保它的`modalPresentationStyle`也被设置! (7认同)
  • @mxcl如果你的viewController的navigationController本身在tabBarController中,那么确保它的modalPresentationStyle也被设置;) (5认同)
  • @alex是的,它很有效:我的错误是将modalPresentationStyle设置为presentVC的UIModalPresentationCurrentContext而不是prenstingVC. (2认同)

Bas*_*ian 20

我使用XCode 7的Interface Builder稍微努力将Presentation Style设置为@VenuGopalTewari建议.在这个版本中,似乎没有Over Current Context或者Over Full Screen是segue的演示模式.因此,为了使其工作,我将模式设置为Default:

在此输入图像描述在此输入图像描述

另外,我将模态呈现的视图控制器的演示模式设置为Over Full Screen:

在此输入图像描述


Ven*_*ari 17

创建一个segue以模态呈现并将该segue的Presentation属性设置为当前上下文它将100%工作

在此输入图像描述

  • 我很佩服100%的经纪人,它有效!关键是将它应用于segue.非常感谢 (3认同)

Ash*_*ale 14

具有透明背景的PresentViewController - 在iOS 8和iOS 9中

MYViewController *myVC = [self.storyboard   instantiateViewControllerWithIdentifier:@"MYViewController"];
    myVC.providesPresentationContextTransitionStyle = YES;
    myVC.definesPresentationContext = YES;
    [myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    [self.navigationController presentViewController:myVC animated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)

并在MYViewController中设置背景颜色为黑色并降低不透明度


Mak*_*Mak 12

这有点hacky方式,但对我来说这个代码有效(iOS 6):

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[self presentViewController:self.signInViewController animated:YES completion:^{
    [self.signInViewController dismissViewControllerAnimated:NO completion:^{
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentViewController:self.signInViewController animated:NO completion:nil];
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    }];
}];
Run Code Online (Sandbox Code Playgroud)

此代码也适用于iPhone


Ted*_*Ted 11

这个类别对我有用(ios 7,8和9)

H档

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end
Run Code Online (Sandbox Code Playgroud)

M文件

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end
Run Code Online (Sandbox Code Playgroud)


dhi*_*hin 9

如果您使用的是Storyboard,则可以按照以下步骤操作:

  1. 添加视图控制器(V2),按照您希望的方式设置UI
  • 添加UIView - 将背景设置为黑色,将不透明度设置为0.5
  • 添加另一个UIView(2) - 将作为你的弹出窗口(请注意UIView和UIView(2)必须具有相同的级别/层次结构.不要使imageview成为视图的子级别,否则uiview的不透明度将影响UIView(2))
  1. 礼物V2模态

  2. 单击segue.在"属性"检查器中,将"演示文稿"设置为"全屏幕".如果你愿意,删除动画

故事板

  1. 选择V2.在"属性"检查器中,将"演示文稿"设置为"全屏幕".检查定义上下文并提供上下文

故事板

  1. 选择V2的MainView(请检查图像).将backgroundColor设置为Clear Color

故事板


Ant*_*ito 7

使用swift解决此问题的方法如下。

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)


ini*_*333 6

我在呈现的视图控制器中的init方法中添加了这三行,并且像魅力一样工作:

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];
Run Code Online (Sandbox Code Playgroud)

编辑(在iOS 9.3上工作):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;
Run Code Online (Sandbox Code Playgroud)

根据文件:

UIModalPresentationOverFullScreen 一种视图演示样式,其中呈现的视图覆盖屏幕.演示文稿完成后,不会从视图层次结构中删除所显示内容下方的视图.因此,如果呈现的视图控制器没有用不透明的内容填充屏幕,则底层内容会显示出来.

适用于iOS 8.0及更高版本.

  • 在 iOS 10.2 上工作。 (2认同)