代码之家  ›  专栏  ›  技术社区  ›  Lawrence

当我在没有动画的情况下推几个控制器时,布局会出错。

  •  3
  • Lawrence  · 技术社区  · 15 年前

    所以我有一堆三个uiTableViewControllers,当我手动点击UI时,每个都在导航栏下面正确地显示它的视图。

    但是,现在我正在通过应用重启恢复状态,所以我在根视图控制器的顶部按相同的两个控制器,一次一个,在主线程中使用相同的方法。最后发生的是中间控制器的视图布置得太低,顶部控制器的视图太高(在导航栏下面)。

    相关代码:

    for (int i = 0; i < [controllerState count]-1; i++) {
        MyViewController* top = (MyViewController*)navigationController.topViewController;
        int key = [[controllerState objectAtIndex:i] integerValue];
        [top restoreNextViewController:key]; // this calls pushViewController: 
        // so top will be different in the next iteration
    }   
    

    我怀疑问题在于我不允许在两次推送之间发生一些重要的UI刷新过程,因为它们发生在同一线程中。它看起来像是自动的视图调整,应该影响顶部控制器,而影响中间的一个。

    对吗?如果是这样的话,我应该怎么做,因为我确实希望所有的状态恢复在应用程序启动后立即进行?

    编辑:看起来我不清楚。 restoreNextViewController: 是一个MyViewController子类方法,该方法基于存储的键恢复控制器的状态,然后使用 [self.navigationController pushViewController:foo animated:NO] . 我这样做是因为我的实际应用程序与这个简化的例子不同,在堆栈中最多有6个控制器,它们并不总是相同的。所以我认为这将是一个比下堆栈检查控制器类更干净的设计。每个控制器都已经知道如何根据用户输入推送子控制器;为什么不在应用程序重启时重用它呢?

    我没有任何麻烦让控制器出现;它们只是被奇怪地摆放着。

    4 回复  |  直到 15 年前
        1
  •  1
  •   Frank Szczerba    15 年前

    您是否考虑让每个视图控制器在 viewWillAppear: ?我只要设置一个 isRestoringState 属性,并在 视图将出现: ,如果已设置,则为该视图运行还原,包括推送任何可见的子视图。类似:

    - (void)viewWillAppear:(BOOL)animated {
        if ([[UIApplication sharedApplication] isRestoringState]) {
            // restore local state, set myChildController if a child is visible
            if (myChildController) {
                [self.navigationController pushViewController:myChildController animated:NO];
            }
        }
    }
    
        2
  •  0
  •   Rob Napier    15 年前

    可以多次调用PushViewController:Animated:请把代码贴出来 -restoreNextViewController . 这段代码为何如此复杂让人困惑。你读过《视图控制器指南》的章节吗? Creating a Nav Controller ?它们包括在启动时在堆栈上推送视图控制器。

        3
  •  0
  •   Ben Clark-Robinson    15 年前

    我同意Rob的观点,我将在加载应用程序时考虑实现uinavigationController。然后按您希望的顺序将每个控制器推到uinavigtioncontroller上。

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    

    因此,如果您知道要将应用程序恢复到什么状态,可以加载要延迟的系列中的适当的ViewController,并将其推送到导航控制器上。

    UIViewController *myViewController = [[UIViewController alloc] initWithNibName:@"myView" bundle:nil];
    [navigationController pushViewController:myViewController animated:NO];
    

    然后,如果您想“弹出”到uiviewcontroller,用户可以免费按导航栏上的“后退”按钮。或者您可以使用

    - (UIViewController *)popViewControllerAnimated:(BOOL)animated
    
    eg [[self navigationController] popViewControllerAnimated:NO];
    

    如果您想自己控制推/弹出,还可以控制是否希望导航栏显示。我希望我已经解释得足够好了,最近我自己也走了这条路。

        4
  •  0
  •   Lawrence    15 年前

    我最终手动重置了每个表视图在其控制器中插入的内容。 viewWillAppear: .