xcode 从 AppDelegate 呈现特定的视图控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9548911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Presenting a specific view controller from AppDelegate
提问by Janum Trivedi
I am trying to present a view controller (a passcode request type view) every time my app becomes active. Once the correct passcode is entered, it should pop off the stack. The passcode view I'm trying to push isn't the initial view controller, so I'm having trouble accessing it from the AppDelegate's applicationDidBecomeActive.
每次我的应用程序变为活动状态时,我都试图呈现一个视图控制器(密码请求类型视图)。一旦输入了正确的密码,它应该从堆栈中弹出。我试图推送的密码视图不是初始视图控制器,所以我无法从 AppDelegate 的 applicationDidBecomeActive 访问它。
I also tried pushing the passcode view from my MainViewController's ViewWillAppear, but it doesn't get called when the app becomes active; only when the screen is refreshed.
我也尝试从我的 MainViewController 的 ViewWillAppear 推送密码视图,但是当应用程序激活时它不会被调用;仅当屏幕刷新时。
I've been researching similar problems across SO the past couple days, but I'm still not understanding the proper method. I've heard that I might not be able to push the view this way because the applicationDidBecomeActive may be called before the Storyboard or NavigationController is connected/initialized/etc.
过去几天我一直在研究类似的问题,但我仍然不理解正确的方法。我听说我可能无法以这种方式推送视图,因为可能在 Storyboard 或 NavigationController 连接/初始化/等之前调用 applicationDidBecomeActive。
If anyone could provide me with the correct way to push/present the view, or if there's somewhere else that'd be better to do this type of thing, I'd appreciate it.
如果有人可以为我提供推送/呈现视图的正确方法,或者如果有其他地方可以更好地执行此类操作,我将不胜感激。
Solved: I just deleted the view from storyboard and used a nib instead. I used:
已解决:我刚刚从故事板中删除了视图,而是使用了笔尖。我用了:
PasscodeUnlockVC *passcodeUnlock = [[PasscodeUnlockVC alloc] initWithNibName:@"PasscodeUnlockVC" bundle:[NSBundle mainBundle]];
[(UINavigationController *)self.window.rootViewController pushViewController:passcodeUnlock animated:NO];
View hierarchy data:
查看层次结构数据:
(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)
采纳答案by rob mayoff
I suggest you use applicationWillEnterForeground:
, not applicationDidBecomeActive:
, because it works better with multitasking gestures. For example, you don't want to put up the lock screen if the user double-clicks the home button to display the task bar, and then dismisses the task bar without changing apps.
我建议你使用applicationWillEnterForeground:
,而不是applicationDidBecomeActive:
,因为它更适合多任务手势。例如,如果用户双击主页按钮显示任务栏,然后在不更改应用程序的情况下关闭任务栏,您不希望挂起锁定屏幕。
Presumably your AppDelegate
has a window
property, and you know that your window's root view controller is a UINavigationController
.
大概你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
}
回答by reza_khalafi
Solved
解决了
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;
Using in applicationWillEnterForegroundmethod.
在applicationWillEnterForeground方法中使用。
回答by msmq
Swift version of Quick and generalised way:
Swift 版本的 Quick 和通用方式:
getRootViewController().presentViewController(messageVC, animated: true, completion: nil)
func getRootViewController() -> UIViewController
{
return (UIApplication.sharedApplication().delegate?.window??.rootViewController)!
}
回答by M Murteza
Here is complete Solution in Swift 4 implement this in didFinishLaunchingWithOptions
这是 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")
}
}
write this Function any where inside Appdelegate.swift
在 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()
}