简体   繁体   English

如果我将应用程序移到后台然后在 iOS 中转到前台,则显示的视图控制器将被关闭

[英]Presented view controller gets dismissed if i move my application to background and then come to foreground in iOS

I had a requirement to cover the screen with black layout when the user moves the application to the background applicationDidEnterBackground in order to maintain the privacy of some sensitive datas on the screen.当用户将应用程序移动到后台applicationDidEnterBackground时,我需要用黑色布局覆盖屏幕,以维护屏幕上某些敏感数据的隐私。 So for this i made use of AppDelegate function to present with a black color in background and then remove that by dismissing it when comes to foreground applicationDidEnterBackground .因此,为此我使用 AppDelegate 函数在背景中呈现黑色,然后通过在前景applicationDidEnterBackground 中关闭它来删除它。 The code is:代码是:

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UIViewController *blankViewController = [UIViewController new];
    blankViewController.view.backgroundColor = [UIColor blackColor];
    [self.window makeKeyAndVisible];
    [self.window.rootViewController presentViewController:blankViewController animated:NO completion:NULL];
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self.window.rootViewController dismissViewControllerAnimated:false completion:nil];
}

@end

Now in my application everything is working fine but in one screen i am presenting a ViewContollerB on a button click by using : [self presentViewController:webview animated:YES completion:nil];现在在我的应用程序中一切正常,但在一个屏幕中,我通过使用以下按钮单击一个ViewContollerB [self presentViewController:webview animated:YES completion:nil]; The application as usually gets covered with black color when moving to background but when i take the application to foreground after this, then the presented ViewContollerB also gets dismissed .当移动到背景时,应用程序通常会被黑色覆盖,但是当我在此之后将应用程序带到前台时,所呈现的ViewContollerB也会被驳回。 How to prevent my presented ViewController to get dismissed once coming from background?如何防止我呈现的 ViewController 一旦来自后台就被解雇?

You are trying to do the following: rootviewcontroller A presents a blank viewcontroller B. Your app goes into background, and you present viewcontroller C from there.您正在尝试执行以下操作:rootviewcontroller A 呈现一个空白的 viewcontroller B。您的应用程序进入后台,然后您从那里呈现 viewcontroller C。 Now B closes as A is presenting both B and C, and that is not allowed.现在 B 关闭,因为 A 同时呈现 B 和 C,这是不允许的。

You will need to check if your rootviewcontroller is presenting any viewcontrollers, and if those are presenting any others recursively.您将需要检查您的 rootviewcontroller 是否正在呈现任何视图控制器,以及这些是否以递归方式呈现任何其他视图控制器。 You can check for those by using the property presentedViewController on a viewcontroller.您可以通过使用视图控制器上的属性presentedViewController来检查这些。

Personally, I would (in a base viewcontroller class that all viewcontrollers inherit from) keep a variable that checks if this one is visible (by keeping track of viewDidAppear and viewDidDisappear ).就个人而言,我会(在所有 viewcontroller 继承的基础 viewcontroller 类中)保留一个变量来检查这个变量是否可见(通过跟踪viewDidAppearviewDidDisappear )。 If this is the one that is visible, you add a blank view on top.如果这是可见的,则在顶部添加一个空白视图。

Answer in Swift because I can't be trusted with Objective-C without an editor:用 Swift 回答,因为如果没有编辑器,我无法信任 Objective-C:

class BaseViewController: UIViewController {
    var appeared = false

    func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated: animated)
        appeared = true
    }

    func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated: animated)
        appeared = false
    }
}

Then you need to fire a notification from the AppDelegate that is caught in this viewcontroller, and then show a blank view on top.然后你需要从这个视图AppDelegate中捕获的AppDelegate触发一个通知,然后在顶部显示一个空白视图。

Create a new 'UIViewController' called OverLayViewController and load it in applicationDidEnterBackground method创建一个名为OverLayViewController的新“UIViewController”并将其加载到applicationDidEnterBackground方法中

- (void)applicationDidEnterBackground:(UIApplication *)application {
    OverLayViewController *blankViewController = [OverLayViewController new];
    blankViewController.view.backgroundColor = [UIColor blackColor];
    [self.window makeKeyAndVisible];
    
    UIViewController *rvc = self.window.rootViewController;
    UIViewController *pvc = rvc.presentedViewController;  // you may need to loop through presentedViewControllers if you have more than one
    if(pvc != nil) {
        [pvc presentViewController: blankViewController animated: NO completion:nil];
    }
    else{
        [self.window.rootViewController presentViewController: blankViewController animated: NO completion:nil];
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    UIViewController *test = [self topViewController];
    if ([test isKindOfClass:[OverLayViewController class]]) {
           [test dismissViewControllerAnimated:false completion:nil];
    }
}


- (UIViewController*)topViewController {
    return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}

-(UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController* tabBarController = (UITabBarController*)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

In this case, dismissViewContoller code wont apply for your webview.在这种情况下, dismissViewContoller代码不适用于您的dismissViewContoller

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS /自动版式:取消已演示的控制器后,更改为演示视图 - IOS/Autolayout: Change to Presenting View After Presented Controller Dismissed 检测何时关闭呈现的视图控制器 - Detect when a presented view controller is dismissed 模态显示/关闭视图控制器时通知? - Notification when view controller is presented modally/dismissed? 为什么我的视图控制器(从故事板中以模态方式呈现)在被解雇后不会被释放? - Why does my view controller (presented modally from a storyboard segue) not get released after being dismissed? iOS执行的UINavigationController执行popViewController后被解雇 - iOS presented UINavigationController gets dismissed after it performs a popViewController 调用viewWillAppear时显示视图控制器的问题被解除 - Issue with calling viewWillAppear of presenting view controller when presented one is dismissed 关闭呈现的视图控制器时如何恢复焦点? - How to restore focus when presented view controller is dismissed? 当通过手势关闭呈现的视图 controller 时如何获得通知? - How to get notified when a presented view controller is dismissed with a gesture? 为什么简单的模态视图控制器在显示和关闭时会滞后? - Why would a simple modal view controller lag when presented and dismissed? TabBarController viewDidAppear 在呈现的视图控制器关闭时未调用 - TabBarController viewDidAppear not called when presented view controller dismissed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM