Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xcode IOS-如何获取当前正在appdelegate中查看的场景/视图_Ios_Objective C - Fatal编程技术网

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

Xcode IOS-如何获取当前正在appdelegate中查看的场景/视图,ios,objective-c,Ios,Objective C,好吧,我对IOS开发有点陌生,但我正在编写一个应用程序,如果用户在我的故事板中的任何特定场景上空闲太长时间,我将使用一个定时器类来超时,这会使用户返回到原始场景/视图。我有一个由多个场景/视图组成的单层板(不确定这里的正确单词是什么),每个场景都有自己的视图控制器 我通过appdelegate类完成超时。请参阅下面的代码 所以我的代码工作正常,效果很好,但我正在努力使它在主场景中忽略计时器 我在谷歌上搜索过这个,阅读了大量的文档,并尝试了很多方法,但到目前为止,我还没有弄清楚如何使用Applic

好吧,我对IOS开发有点陌生,但我正在编写一个应用程序,如果用户在我的故事板中的任何特定场景上空闲太长时间,我将使用一个定时器类来超时,这会使用户返回到原始场景/视图。我有一个由多个场景/视图组成的单层板(不确定这里的正确单词是什么),每个场景都有自己的视图控制器

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

所以我的代码工作正常,效果很好,但我正在努力使它在主场景中忽略计时器

我在谷歌上搜索过这个,阅读了大量的文档,并尝试了很多方法,但到目前为止,我还没有弄清楚如何使用ApplicationIDTimeout方法获取当前查看的场景

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

有人知道怎么做吗

谢谢你抽出时间

#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

我想你已经把计时器的逻辑写在什么地方了。当你弹出回到rootViewController时,你能让计时器失效吗

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

if (![navigation.viewControllers containsObject:viewController] {
   // push onto the stack
}
您还可以通过检查ViewController数组的计数来检查navigationController中当前有多少层,如下所示:

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

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

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

这与您当前的代码不同,因为您的主页不会在每次计时器关闭时被删除和重新创建。我把这条路弄得太复杂了

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

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

[myAppDelegate setSceneName:self.title]


轻松点

我知道获取“当前查看视图”的一种方法是获取顶部窗口。您可以说UIViewController*topView=self.window.subview[0];好的,我试试这个谢谢!好的,所以当我在调试模式下访问topView并检查它的属性时,它并没有给我任何有用的信息来识别它。例如,它的标题是零。一旦我有了topView,我需要用它做什么来确定我在哪个场景?再次感谢您的帮助。我已经想出了一个解决方案,明天将发布!对逻辑被写入一个类文件中,并启动它在main.m中运行。我会试试你的想法,然后再给你回复#导入#导入“StoryboardAppDelegate.h”#导入“TIMERUIApplication.h”int main(int argc,char*argv[]){@autoreleasepool{返回UIApplicationMain(argc,argv,NSStringFromClass([TIMERUIApplication class]),NSStringFromClass([StoryboardAppDelegate class]);}当我得到viewcontrollers的数量时,它似乎总是1,而不是0。我想这可能是因为我以编程方式声明了导航控制器?另外,我希望避免使计时器无效,因为这是一件需要管理的棘手事情,如果可能的话,我希望允许它在应用程序的整个生命周期中继续运行。还有其他想法吗?谢谢是否每次应用程序超时时都要创建新的NavigationViewController?这就是你想要的吗?也许您需要将navigationViewController存储为属性,并继续从其堆栈中推/弹出。是的,我敢打赌您是正确的。我真的不太了解如何使用它们,这是我找到的一些很好的代码,我不需要在开发环境中进行设置。你知道我可以从哪些文章或代码示例中获得一些想法吗?谢谢谢谢,我将试一试。当我尝试使用您使用的代码获取计数时,会出现异常“无法识别的选择器发送到实例UIViewController”。因此,我修改了您告诉我的内容,并使用我的导航实例调用count属性,在我的代码中,无论我在哪个场景中,count始终等于1。也许我的应用程序架构不正确;我对这个很陌生。还有什么想法吗?谢谢你的时间。我刚刚想出了一个解决这个问题的简单方法。因为我今天才加入,所以直到明天我才会发布解决方案。我明天将发布我的解决方案。=)谢谢大家的帮助。从.net编码到MaciOS开发工作都很有趣。如此不同,但我真的很喜欢它,它只是需要时间来理解一种新的做事方式