从AppDelegate启动ViewController

13

我有一个自定义的URL Scheme,希望能够在打开此URL时跳转到非根视图控制器ViewController。我已经成功实现了这一点,现在需要将该ViewController推入navigationController中,而我是在AppDelegate中处理此URL的,请问应该如何操作?

- (BOOL)application:(UIApplication *)application
     openURL:(NSURL *)url
     sourceApplication:(NSString *)sourceApplication
     annotation:(id)annotation {

if ([[url scheme] isEqualToString:@"njoftime"]) {

    NSDictionary *getListingResponse = [[NSDictionary alloc]init];
    getListingResponse = [Utils getListing:[url query]];;

    if ([[getListingResponse objectForKey:@"status"] isEqualToString:@"success"]) {
         ListingViewController *listingView = [[ListingViewController alloc]init];
         [self.window.rootViewController.navigationController pushViewController:listingView animated:YES];
         return YES;
    }

但它只启动了我的应用程序,没有我想要启动的ListingViewController。 有什么别的办法吗?


你有收到任何错误吗? - nikhil84
无需操作,应用程序会在其根视图控制器上正常启动。 - Elgert
你尝试设置断点并检查是否进入了第二个if语句吗? - jomafer
从我所看到的,您说一切都是通过编程创建的,如果没有故事板,那么您在哪里设置rootViewController? - E-Riddie
有1个故事板,只有rootViewController被创建,其他所有内容都是通过编程方式创建的。现在我发现它确实启动了活动,但是需要10-15秒钟的延迟。@jomafer 是的,它确实进入了,我在那里有NSLog,但我在发布这里时已将其删除。 - Elgert
如果您正在同步模式下从服务器下载数据,并且依赖于其响应,则延迟是正常的(但不太用户友好)。无论如何,我已经发布了一个关于如何呈现和解除viewController的答案,如果您需要更多澄清,请编辑您的答案或提出另一个问题。 :) - E-Riddie
6个回答

13

问题

要处理从AppDelegatepushpop视图控制器,需要使用[UIApplication sharedApplication],它跟踪所有的视图控制器,从根视图控制器开始。


解决方案

AppDelegatePUSH视图控制器:

ListingViewController *listingVC = [[ListingViewController alloc] init];
[(UINavigationController *)self.window.rootViewController pushViewController:listingVC animated:YES];

要关闭你刚刚呈现的ViewController,你需要使用这段代码:POP

[(UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController popViewControllerAnimated:YES ];


1
这种方式也会创建一个新的导航控制器。正确的方法是这样的UINavigationController * nav =(UINavigationController *)self.window.rootViewController; [nav pushViewController:listingView animated:YES];但问题是延迟,而且不是服务器的延迟,因为我可以在控制台上看到它只有100毫秒。 - Elgert
如果你需要推送它,你只需从 navigationController 推送,这是 rootViewController。关于延迟,你说 viewControllers 是通过编程方式加载的?如果你在 viewDidLoad 上创建东西,那么将它们移动到 viewDidAppear,并给我反馈。 - E-Riddie
相同的,大约7秒,这不正常。 - Elgert
移除在viewWillAppear、viewDidAppear和viewDidLoad中初始化的所有操作和方法,以查看您的视图控制器或它们正在加载的数据是否存在问题。 - E-Riddie
1
没事了,我解决了。我是在后台线程中推送ViewController而不是主线程中。现在它启动得很快。我感觉很愚蠢 -_- - Elgert
我很高兴你解决了它! :) - E-Riddie

7
如果您正在使用Storyboard,则可以使用以下行将您的VC推送。
 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
 YOURCLASS *obj=[storyboard instantiateViewControllerWithIdentifier:@"YOUR_CLASS_STORYBOARD_ID"];
[self.window.rootViewController.navigationController pushViewController:obj animated:YES];

更新:

ListingViewController *listingVC = [[ListingViewController alloc] init];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:listingVC];
[self.window.rootViewController presentViewController:navCon animated:YES completion:nil];

所有的视图控制器都是通过编程创建并推送的,没有使用StoryBoard。 - Elgert
然后在你的ListingViewController的分配中,你应该使用initWithNib - nikhil84
好的,你需要重新检查你的代码,因为它可能没有获取到任何视图来加载,导致屏幕空白(如果这是你所看到的情况)。 - nikhil84
我没有遇到空白屏幕的问题,应用程序正常打开但是没有推送ViewController。使用presentModalView可以解决问题,但我的整个项目都基于navigationController,之后无法导航,因此无法使用presentModalView - Elgert
现在它“有点工作”。视图控制器已打开,但这会创建一个新的导航控制器,我通常没有的返回按钮:P - Elgert
哈哈哈!!!...回到正题,用您的导航控制器obj替换UINavigationController obj或将其作为子VC添加到rootVC.navigation中。然后告诉我。 - nikhil84

2
在didFinishingWithLaunchingOptions方法中编写此代码。
  SecViewController *Vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"second"];
   [(UINavigationController *)self.window.rootViewController pushViewController:Vc animated:YES];

1
对于Swift 3版本:
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UINavigationController = mainStoryboardIpad.instantiateViewController(withIdentifier: "initial") as! UINavigationController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()

0

你的AppDelegate.m应该长这样:

#import "TestViewController.h"

@interface AppDelegate ()

@property (strong, nonatomic) TestViewController *viewController;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  self.viewController = [[TestViewController alloc]init];
  self.window.rootViewController = self.viewController;
  [self.window makeKeyAndVisible];

  return YES;
}

0
如果您想要推送一个UIViewController,可能忘记使用N​​ibName进行初始化了:
LoginViewController *loginViewController = [[LoginViewController alloc]initWithNibName:@"LoginViewController" bundle:nil];

视图控制器是通过代码创建的,没有Storyboard,也没有Nib。 - Elgert

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