Xcode IOS - 如何获取当前正在appdelegate中查看的场景/视图

时间:2014-02-19 15:11:23

标签: ios objective-c

好吧我对IOS开发有点新意,但是我正在编写一个应用程序,我在使用计时器类来超时用户,如果他们在我的故事板中的任何特定场景上闲置太久并且它会使用户回到原始场景/视图。我有一个故事板,由几个场景/视图组成(不知道这里的正确字是什么),每个场景都有自己的视图控制器。

我通过appdelegate类完成超时。请参阅下面的代码。

所以我有代码工作,它工作得很好,但我试图使它,如果我们在主场景,它将忽略计时器。

我已经搜索了这个,阅读了大量的文档,并尝试了很多东西,但到目前为止,我还没有能够弄清楚如何在applicationDidTimeout方法中获取当前查看的场景。

如果我可以获取当前查看的场景/视图的名称,那么我可以选择忽略计时器。

有谁知道怎么做?

感谢您的时间。

#import "StoryboardAppDelegate.h"

#import "TIMERUIApplication.h"

@implementation StoryboardAppDelegate

@synthesize window = _window;

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

{

    // applicaiton has timed out

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];

    return YES;

}

-(void)applicationDidTimeout:(NSNotification *) notif

{

    NSLog (@"time exceeded!!");



    UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:NULL] instantiateViewControllerWithIdentifier:@"StoryboardViewController"];



    UINavigationController * navigation = [[UINavigationController alloc]initWithRootViewController:controller];



    [self.window setRootViewController:navigation];

    navigation.delegate = self;

    navigation.navigationBarHidden = YES;

    if (controller) {

        @try {

            [navigation pushViewController:controller animated:NO];

        } @catch (NSException * ex) {

            //“Pushing the same view controller instance more than once is not supported”

            //NSInvalidArgumentException

            NSLog(@"Exception: [%@]:%@",[ex  class], ex );

            NSLog(@"ex.name:'%@'", ex.name);

            NSLog(@"ex.reason:'%@'", ex.reason);

            //Full error includes class pointer address so only care if it starts with this error

            NSRange range = [ex.reason rangeOfString:@"Pushing the same view controller instance more than once is not supported"];



            if ([ex.name isEqualToString:@"NSInvalidArgumentException"] &&

                range.location != NSNotFound) {

                //view controller already exists in the stack - just pop back to it

                [navigation popToViewController:controller animated:NO];

            } else {

                NSLog(@"ERROR:UNHANDLED EXCEPTION TYPE:%@", ex);

            }

        } @finally {

            //NSLog(@"finally");

        }

    } else {

        NSLog(@"ERROR:pushViewController: viewController is nil");

    }

    [(TIMERUIApplication *)[UIApplication sharedApplication] resetIdleTimer];

}

@end

3 个答案:

答案 0 :(得分:0)

我假设你已经在某处编写了计时器的逻辑。当你弹回rootViewController时,你可以让计时器失效吗?

此外,您不应将viewController推送到navigationViewController并处理错误,而应检查您正在推送的控制器是否已经在堆栈中,如下所示:

if (![navigation.viewControllers containsObject:viewController] {
   // push onto the stack
}

您还可以通过检查viewControllers数组的计数来检查navigationController中当前有多少级别,如下所示:

if ([navigation.viewControllers count] == 0) {
   // I know we're on the main screen because no additional viewControllers have been added to the stack.
}

答案 1 :(得分:0)

如果您没有在任何地方使用模态控制器,那么最简单的解决方案就是

UINavigationController* nav = (UINavigationController*)self.window.rootViewController; // You could just save the nav as part of your app delegate
if (nav.viewControllers.count > 1){
  [nav popToRootViewControllerAnimated:YES];
}

这与您当前的代码不同,因为每次定时器关闭时您的主页都不会被删除并重新创建

答案 2 :(得分:0)

好的,我想出了如何做到这一点。我这样做太复杂了。

为了解决这个问题,我在app delegate类中创建了一个属性和方法,我可以在其中设置一个场景名称。

然后在每个视图控制器头文件中,我导入app delegate类的头文件并定义对它的引用。然后在每个视图的load事件中,我只需使用这行代码在app delegate类中设置场景名称。

[myAppDelegate setSceneName:self.title];

轻松自在!