【问题标题】:Objective c - Detect current view from appDelegate目标 c - 从 appDelegate 检测当前视图
【发布时间】:2014-09-07 18:10:00
【问题描述】:

我正在使用 modal segue(没有导航控制器)在 viewController A 和 viewController B 之间移动,如下所示:

viewA *first = [self.storyboard instantiateViewControllerWithIdentifier:@"viewA"];
[self presentViewController:first animated:YES completion:nil];

然后向后移动:

 [self dismissViewControllerAnimated:YES completion:nil]; 

现在,我想从 AppDelegate 知道 A 还是 B 是当前视图。 问题是当我检查时

[(AppDelegate *)[[UIApplication sharedApplication] delegate] window]

答案始终是视图 A - 第一个。

每次使用模态转场时,我都尝试设置当前视图,如下所示:

viewA *first = [self.storyboard instantiateViewControllerWithIdentifier:@"viewA"];
    [self presentViewController:first animated:YES completion:^
{
[[(AppDelegate *)[[UIApplication sharedApplication] delegate] window] setRootViewController:first];
}];

但这会导致一些错误(例如无法使用“dismissViewControllerAnimated”),并且不可能在具有许多segue的大项目中的每个segue中都这样工作。

我应该如何处理它?以及我应该如何以更合适的方式检测当前视图?

【问题讨论】:

    标签: ios objective-c uiviewcontroller


    【解决方案1】:

    正如here所回答的那样

    UIWindow *topWindow = [[[UIApplication sharedApplication].windows sortedArrayUsingComparator:^NSComparisonResult(UIWindow *win1, UIWindow *win2) {
        return win1.windowLevel - win2.windowLevel;
    }] lastObject];
    
    UIView *topView = [[topWindow subviews] lastObject];
    

    但是,在这里执行此逻辑听起来像是糟糕的架构。您需要知道 AppDelegate 中当前呈现的是哪个视图的原因是什么?

    编辑您似乎想从您的视图控制器响应applicationWillResignActive 事件。在你的游戏视图控制器中使用类似的东西。

    - (void) applicationWillResign {
        NSLog(@"About to lose focus");
    }
    
    -(void) viewDidLoad {
        [super viewDidLoad];
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(applicationWillResign)
         name:UIApplicationWillResignActiveNotification
         object:NULL];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
        [[NSNotificationCenter defaultCenter]
         removeObserver:self];
    }
    

    【讨论】:

    • 我有一个游戏。 viewA 是主菜单,viewB 是游戏本身。每次应用程序移至后台(applicationWillResignActive)时,我都想暂停游戏。所以我需要知道当前视图是否调用 pause 方法(因为如果我在主菜单或其他地方,我不需要调用它)。这是其中一个例子。在我所有的应用程序中,我只使用模态 segue,当我需要从 appDelegate 调用一些方法时,我必须知道当前视图是什么。这就是我的工作方式,但也许它是错误的。所以,如果我做错了什么,我想知道:)
    • @AsiGivati 这是一个非常真实的原因。 here 给出了更好的解决方案。
    • 太棒了!与 NSNotificationCenter 完美配合 :)
    • @AsiGivati Also already answered, a lot of times。下次问之前多咨询谷歌。
    【解决方案2】:

    appDelegate 的窗口不等于任何一个视图控制器(viewControllerA 或 viewControllerB)。您可以向窗口询问它的根视图控制器...

    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    
    if (appDelegate.window.rootViewController == viewControllerA) {
        // always true if you always start the app with viewControllerA
    

    ...您可以向任何视图控制器询问它呈现的视图控制器...

    if (appDelegate.window.rootViewController.presentedViewController == viewControllerB) {
       // will be true if viewControllerA has presented viewControllerB
    

    但这是一个棘手的游戏。例如,如果 viewControllerB 呈现了其他一些 viewControllerC,则上述条件将继续为真。

    查看@Eric 答案here(不是公认的答案),了解一般查找最顶层 vc 的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-19
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多