从AppDelegate中呈现特定的视图控制器

8
我正在尝试在我的应用程序变为活动状态时每次呈现一个视图控制器(一种密码请求类型视图)。输入正确的密码后,它应该从栈中弹出。我要推送的密码视图不是初始视图控制器,所以我无法从AppDelegate的applicationDidBecomeActive访问它,这是我的困扰所在。
我还尝试了从MainViewController的ViewWillAppear推送密码视图,但它只在屏幕刷新时调用,而不是在应用程序变为活动状态时调用。
我已经在Stack Overflow上研究了过去几天类似的问题,但我仍然不理解正确的方法。我听说可能无法以这种方式推送视图,因为在Storyboard或NavigationController连接/初始化等之前可能会调用applicationDidBecomeActive。
如果有人能向我提供推送/呈现视图的正确方法,或者如果有其他更好的地方可以完成此类事情,我将不胜感激。
解决方法:我只是从故事板中删除了视图,并改用nib。我使用:
PasscodeUnlockVC *passcodeUnlock = [[PasscodeUnlockVC alloc] initWithNibName:@"PasscodeUnlockVC" bundle:[NSBundle mainBundle]];
[(UINavigationController *)self.window.rootViewController pushViewController:passcodeUnlock animated:NO];

查看层次结构数据:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription]
<UIWindow: 0x736a4b0; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x7367b40>>
   | <UILayoutContainerView: 0x76977a0; frame = (0 0; 320 480); autoresize = W+H; layer =     <CALayer: 0x769de60>>
   |    | <UINavigationTransitionView: 0x7692110; frame = (0 0; 320 480); clipsToBounds = YES;      autoresize = W+H; layer = <CALayer: 0x769a8c0>>
   |    |    | <UIViewControllerWrapperView: 0x73868d0; frame = (0 64; 320 416); autoresize =  W+H; layer = <CALayer: 0x75510e0>>
   |    |    |    | <UIView: 0x76b93e0; frame = (0 0; 320 416); autoresize = W+H; layer = <CALayer: 0x7386850>>
   |    | <UINavigationBar: 0x73664b0; frame = (0 20; 320 44); clipsToBounds = YES; opaque =  NO; autoresize = W; layer = <CALayer: 0x7366550>>
   |    |    | <UINavigationBarBackground: 0x7360ea0; frame = (0 0; 320 44); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7366520>> - (null)
   |    |    | <UINavigationItemView: 0x76b95e0; frame = (160 21; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x76aa8e0>>
   |    |    | <UINavigationItemButtonView: 0x7550650; frame = (5 7; 73 30); opaque = NO;   userInteractionEnabled = NO; layer = <CALayer: 0x7368b40>>
Current language:  auto; currently objective-c
(gdb) 

我不熟悉 viewDidBecomeActive 消息,当我在 developer.apple.com 上搜索时,没有找到任何结果。也许您应该告诉我们更多关于这个方法的信息,甚至展示您的代码。 - rob mayoff
对不起,我的意思是applicationDidBecomeActive。我会编辑帖子的。 - Janum Trivedi
我正在尝试复制您的模态视图显示,但它告诉我pushViewController:animated未被识别,您能告诉我是否在iOS 6上尝试过吗? - perrohunter
4个回答

4
我建议您使用 applicationWillEnterForeground: 而不是 applicationDidBecomeActive:,因为它在处理多任务手势时效果更好。例如,如果用户双击主屏幕按钮显示任务栏,然后关闭任务栏而不切换应用程序,您不希望出现锁定屏幕。

假设您的 AppDelegate 有一个 window 属性,并且您知道窗口的根视图控制器是 UINavigationController

- (void)applicationWillEnterForeground:(UIApplication *)application {
    PasscodeViewController *pvc = [[PasscodeViewController alloc] init];
    [(UINavigationController *)self.window.rootViewController pushViewController:pvc animated:NO];
    // [pvc release]; if not using ARC
}

我实现了那段代码,没有任何警告或错误,但是它只显示导航栏和下面的黑屏,而不是整个视图。有什么想法吗?我不需要在头文件中声明视图吗?再次感谢。 - Janum Trivedi
在调试器中暂停并执行 po [[(id)UIApp keyWindow] recursiveDescription] - rob mayoff
好的,我已经获取了有关视图层次结构的信息,但我不确定如何解析/使用它。 SO上的其他人也遇到了黑屏的同样问题,解决方案是删除loadView实现,但我没有这个方法。 - Janum Trivedi
请在您的问题中放置视图层次结构转储,以便我可以查看它。 - rob mayoff
好的,我在转储中看到一个视图(0x76b93e0),它可能属于您的PasscodeViewController。您需要弄清楚为什么它没有正确设置。视图控制器是否有nib文件?它的名称是PasscodeViewController.xib吗? - rob mayoff

0

已解决

PasscodeViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"passcodeVCID"]; 
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:vc];
navController.navigationBar.hidden = YES;
vc.mode = @"enable";
self.window.rootViewController = navController;  

applicationWillEnterForeground方法中使用。


0

快速且通用的Swift版本:

getRootViewController().presentViewController(messageVC, animated: true, completion: nil)

func getRootViewController() -> UIViewController
{
    return (UIApplication.sharedApplication().delegate?.window??.rootViewController)!
}

-1

以下是Swift 4的完整解决方案,请在didFinishLaunchingWithOptions中实现

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

 let isLogin = UserDefaults.standard.bool(forKey: "Islogin")
    if isLogin{
        self.NextViewController(storybordid: "OtherViewController")


    }else{
        self.NextViewController(storybordid: "LoginViewController")

    }
}

将此函数编写到Appdelegate.swift文件的任何位置

  func NextViewController(storybordid:String)
{

    let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
   // self.present(exampleVC, animated: true)
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = exampleVC
    self.window?.makeKeyAndVisible()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接