的iOS:模态的ViewController与透明背景(iOS: Modal ViewControl

2019-06-18 10:32发布

我试图呈现视图控制器模态,具有透明背景。 我的目标是让在同一时间内同时显示的呈现和展示视图控制器的看法。 问题是,当呈现动画完成,呈现视图控制器的视野中消失。

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

我知道我可以只添加视图作为一个子视图,但我想避免这种情况的解决方案出于某种原因。 我怎么能解决这个问题?

Answer 1:

这下面的代码只能在iPad上。

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

我会去增加一个子视图。

这里是一个很好的讨论。 看看具体的意见。 不仅答案。

模式的看法

如果我是你,我不会去做。 我想补充一个子画面,并做到这一点。 这似乎给我过的东西更好的控制。

编辑:

由于自iOS 8的提及保罗Linsay,所有需要的是UIModalPresentationOverFullScreen呈现的视图控制器的modalPresentationStyle。 这也将覆盖的导航栏和TabBar按钮。



Answer 2:

对于那些试图让这个在iOS 8的工作,“苹果批准”的方式来显示一个透明的模态视图控制器是通过设置modalPresentationStyle 控制器上 UIModalPresentationOverCurrentContext

这可以在代码中,或通过设置在故事板的SEGUE的特性来完成。

从UIViewController的文档:

UIModalPresentationOverCurrentContext

其中显示了仅父视图控制器的内容内容的呈现风格。 所呈现的内容下方的意见时,演示结束不会从视图层次结构中移除。 因此,如果出现的视图控制器不填充不透明内容的屏幕,下方的内容显示出来。

当在酥料饼呈现视图控制器,此演示文稿的风格,才支持的过渡风格UIModalTransitionStyleCoverVertical。 尝试使用不同的过渡风格触发一个例外。 然而,可以使用其它的过渡样式(除了局部卷曲转变)如果父视图控制器不处于酥料饼。

可用在IOS 8.0及更高版本。

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

从WWDC 2014“视图控制器的进步中的iOS 8”视频进入这在一些细节上。

注意:

  • 一定要给您介绍的视图控制器明确的背景颜色,以免它实际上不是看穿!
  • 你必须在提交即设置此参数之前设置这个viewDidLoad的presentedViewController不会有任何影响


Answer 3:

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



Answer 4:

此代码iOS6的和iOS7下正常工作在iPhone上:

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

在这种情况下,你错过幻灯片上的动画。 要保留动画你仍然可以使用下面的“非优雅”扩展:

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

如果我们的presentingV所在的UINavigationController或的UITabBarController内你需要与控制器作为presentingVC操作。

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

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

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

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

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

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

的最后一件事是定义在自定义过渡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
    }
}


Answer 5:

我挣扎有点与的XCode 7的界面生成器设置信息的呈现样式作为@VenuGopalTewari建议。 在这个版本中,似乎没有Over Current Context还是Over Full Screen显示模式为SEGUE。 因此,为了使其工作,我将模式设置为Default

另外我设置了模态呈现视图控制器的呈现模式Over Full Screen



Answer 6:

创建顺着接下去模态存在,且赛格瑞的呈现属性设置为在目前情况下,将工作100%



Answer 7:

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

而在MYViewController设置背景色黑色,不透明度降低



Answer 8:

这是一个有点哈克的方式,但对我这个代码的工作(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;

    }];
}];

此代码的工作也在iPhone



Answer 9:

这一类工作对我来说(IOS 7,8和9)

.h文件

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

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


Answer 10:

我加在呈现视图控制器init方法这三条线,并且就像一个魅力:

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

EDIT(在iOS 9.3的工作):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

按照文档:

UIModalPresentationOverFullScreen其中所提出的观点涵盖了画面的图呈现样式。 所呈现的内容下方的意见时,演示结束不会从视图层次结构中移除。 因此,如果出现的视图控制器不填充不透明内容的屏幕,下方的内容显示出来。

可用在IOS 8.0及更高版本。



Answer 11:

如果您使用的脚本,可以按照此步骤:

  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来清除颜色



Answer 12:

另一种方法是使用一个“容器视图”。 只是让阿尔法低于1,并与塞克嵌入。 的XCode 5,目标iOS7。 在测试了iPhone。

从iOS6的容器视图。 链接到博客文章说。



Answer 13:

该解决方案使用SWIFT是如下这个答案。

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContent
present(vc, animated: true, completion: nil)


Answer 14:

我已经创建了一个对象来处理我所说的“叠加态”的演讲,这意味着它保留了背景的看法,并允许你有一个透明背景的一个模式。

它有,这是否一个单一的,简单的方法:

- (void)presentViewController:(UIViewController *)presentedViewController
       fromViewController:(UIViewController *)presentingViewController
{
    presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    presentedViewController.transitioningDelegate = self;
    presentedViewController.modalPresentationCapturesStatusBarAppearance = YES;

    [presentedViewController setNeedsStatusBarAppearanceUpdate];

    [presentingViewController presentViewController:presentedViewController
                                       animated:YES
                                     completion:nil];
}

设置是很重要的modalPresentationCapturesStatusBarAppearance属性为YES ,并迫使状态栏外观进行更新,如果你提出的视图控制器具有不同的preferredStatusBarStyle

这个对象应该有一个@property (assign, nonatommic) isPresenting

你想这个对象遵守的UIViewControllerAnimatedTransitioningUIViewControllerTransitioningDelegate协议和实现以下方法:

- (id)animationControllerForPresentedController:(UIViewController *)presented
                           presentingController:(UIViewController *)presenting
                               sourceController:(UIViewController *)source
{
    self.isPresenting = YES;

    return self;
}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed
{
    self.isPresenting = NO;

    return self;
}

和:

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

- (void)animateTransition:(id)transitionContext
{
    UIViewController* firstVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* secondVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView* containerView = [transitionContext containerView];
    UIView* firstView = firstVC.view;
    UIView* secondView = secondVC.view;

    if (self.isPresenting) {
        [containerView addSubview:secondView];
        secondView.frame = (CGRect){
            containerView.frame.origin.x,
            containerView.frame.origin.y + containerView.frame.size.height,
            containerView.frame.size
        };

        firstView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        [UIView animateWithDuration:0.25 animations:^{
            secondView.frame = containerView.frame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        } else {
        [UIView animateWithDuration:0.25 animations:^{
            firstView.frame = (CGRect){
                containerView.frame.origin.x,
                containerView.frame.origin.y + containerView.frame.size.height,
                containerView.frame.size
        };

        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

这确实滑入-来自该底部动画模拟的默认模式的动画,但你可以把它任何你想要的。

重要的是,呈现视图控制器的观点,将继续留在后面,让您创建一个透明的效果。

该解决方案适用于iOS的7+



Answer 15:

这样做(使用一个非常简单的方法Storyboards ,例如)是:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SomeStoryboardViewController"];
// the key for what you're looking to do:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view.alpha = 0.50f;

[self presentViewController:vc animated:YES completion:^{
    // great success
}];

这将呈现UIViewControllerStoryboard模态,但有一个半透明的背景。



Answer 16:

要在这里回顾一下所有的好答案和意见,并仍然有一个动画,同时移动到新ViewController这是我做过什么:(支持的iOS 6及以上)

如果您使用UINavigationController \ UITabBarController这是要走的路:

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

如果你这样做,你将失去你modalTransitionStyle动画。 为了解决这个问题,你可以轻松地添加到您的SomeViewController类这样的:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}


Answer 17:

工作于iOS 7-10

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}


Answer 18:

当然,你应该设置UIModalPresentationCurrentContext,但设置clearColor的地方也很重要! 您不能设置背景viewDidLoad中的功能,将其设置视图做负载像根视图控制器或在要提出控制器的初始化函数之前!

actionController.view.backgroundColor = [UIColor clearColor];
[self presentViewController:actionController animated:YES completion:nil];

要么

- (instancetype)init {

    self = [super initWithNibName:nil bundle:nil];

    if(self) {
        self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self.view setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}


Answer 19:

如果您使用的模式SEGUE,请务必将其设置为这个图像(如果你愿意,你可以关闭动画)



Answer 20:

一个完整的方法在iOS 7和iOS 8进行测试。

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end


Answer 21:

在的appdelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[_window rootViewController]setModalPresentationStyle:UIModalPresentationCurrentContext];
    return YES;
}

在从那里你必须加载下一个视图,你第一个视图控制器:

  NextViewController *customvc = [[NextViewController alloc]init];
    [self presentViewController:customvc animated:YES completion:^{

    }];

在nextViewController这是要添加透明:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view insertSubview:backView atIndex:0];
}


Answer 22:

登录屏幕是一个模式,这意味着它坐落在前面的屏幕上方。 到目前为止,我们已经模糊的背景,但它没有任何模糊; 它只是一个灰色背景。

我们需要正确地设置我们的情态。

图像链接目标

  • 首先,我们需要改变视图控制器的视图背景清晰的彩色。 它只是意味着它应该是透明的。 默认情况下,视图是白色的。

  • 其次,我们需要选择导致登录屏幕Segue公司,并在属性检查器中,将呈现给在当前上下文。 此选项仅适用于自动布局和启用大小级。

图像链接目标



Answer 23:

设置导航的modalPresentationStyleUIModalPresentationCustom

并设置您呈现视图控制器的背景色为色彩分明。



Answer 24:

雨燕4.2

guard let someVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someVC") as? someVC else {
    return
}
someVC.modalPresentationStyle = .overCurrentContext

present(someVC, animated: true, completion: nil)


文章来源: iOS: Modal ViewController with transparent background