【问题标题】:Changing UIViewController from AppDelegate on ios for push notification从 iOS 上的 AppDelegate 更改 UIViewController 以进行推送通知
【发布时间】:2013-12-13 00:02:14
【问题描述】:

当用户收到推送通知时,我希望应用打开某个 UIViewController。我在带有故事板的 xCode 5 中。

我认为我的代码很接近,但它抛出了一个错误

这是AppDelegate中的方法

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    UINavigationController *nav = (UINavigationController *)self.window.rootViewController;
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
    RewardList *vc = (RewardList *)[storyboard instantiateViewControllerWithIdentifier:@"RewardList"];
    [nav pushViewController:vc animated:YES];
}

[nav pushViewController:vc animated:YES]; 上出现错误我不太确定发生了什么。有人可以帮助阐明这个问题吗?

这是错误:

-[SplashViewController pushViewController:animated:]: unrecognized selector sent to instance 0x1f862630 2013-12-12 17:58:28.719 appName[473:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SplashViewController pushViewController:animated:]: unrecognized selector sent to instance 0x1f862630'

编辑: 应用根视图控制器是 SplashNavigationController,它是一个 UIViewController。从那里我有一个 UITabBarController。在我的第三个标签里面,是 RewardList,它也是一个 UIViewController。我需要从当前视图转到我的第三个选项卡,即 RewardList 选项卡。

我在这方面找到了很多帖子,但在我的情况下似乎没有任何效果。

【问题讨论】:

  • 你确定 nav 是 UINavigationController 吗?
  • 在不知道情节提要中的视图控制器层次结构的情况下很难回答您的问题。从错误中可以清楚地看出,窗口的根视图控制器是 SplashViewController,而不是 UINavigationController。那么,你的层次结构是什么?
  • 感谢所有回复。我不清楚层次结构是如何工作的。一直在尝试找到有关此的教程以更好地理解它。我对我的帖子进行了编辑,以提供有关层次结构的更多信息。如果需要更多信息,请告诉我。

标签: ios iphone objective-c uiviewcontroller


【解决方案1】:

我要解决这个问题的第一件事是改变结构,使标签栏控制器成为窗口的根视图控制器。如果您希望您的初始屏幕首先出现,然后在第一个选项卡的控制器中的 viewDidAppear 方法中以模态方式(没有动画)呈现该屏幕。完成该屏幕后,您可以将其关闭,然后您将进入第一个控制器。如果您进行了更改,那么在应用程序委托中执行您想要的操作将很简单,

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
         UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;
         tbc.selectedIndex = 2;
  }

我还建议您学习 Apple 的“iOS 视图控制器编程指南”以了解视图控制器及其生命周期。

【讨论】:

    【解决方案2】:

    听起来你的根视图控制器是 SplashViewController 类的视图控制器。 SplashViewController 是 UINavigationController 的子类吗?它必须是,否则你会得到那个错误。

    【讨论】:

    • 啊,不是。它是 UIViewController 的子类。 RewardList 也是 UIViewController 的子类,但它有一个导航控制器。所以我猜 nav 是我的 SplashViewController 因为我的故事板默认为它。我仍然不清楚如何从当前的 UIViewController 更改为 RewardList UIViewController
    【解决方案3】:

    有一些方法可以在这个线程上获得最顶层的视图控制器。 https://stackoverflow.com/a/23603265/

    我喜欢这段代码,因为它非常简单。 https://stackoverflow.com/a/23603265/1971596

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

    然后您只需从最顶层的视图控制器展示视图控制器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      相关资源
      最近更新 更多