在 iPhone 上使用 UINavigationController 中的 setViewController 行为不正常

发布于 2024-10-06 01:08:17 字数 1616 浏览 1 评论 0原文

我在使用 UINavigationController 的 iPhone 应用程序时遇到问题。当我使用 PushNavigationController 时,它工作正常。 iPhone 在切换到下一个 ViewController 时执行动画。但是,当使用 ViewController 数组和 setViewControllers 方法时,动画中会出现一个故障,该故障可能会发展为清晰可见的动画错误。

以下代码片段在根 ViewController 中调用。根据情况,它应该切换到 ViewController1,或者直接转到 ViewController2。在后一种情况下,用户可以导航回 vc1,然后导航到根目录。

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack
[viewControllers addObject:self];
// add first VC
AuthentificationViewController* authentificationViewController =
  [[[AuthentificationViewController alloc] initWithNibName:@"AuthentificationViewController" bundle:nil] autorelease];
[viewControllers addObject:authentificationViewController];

if (someCondition == YES)
{
 UserAssignmentsListViewController* userAssignmentsListViewController =
      [[[UserAssignmentsListViewController alloc] initWithNibName:@"UserAssignmentsOverviewViewController" bundle:nil] autorelease];

 [viewControllers addObject:userAssignmentsListViewController];
}

[self.navigationController
  setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];

正如您所看到的,我将向数组添加第一个和第二个 VC,最后用动画设置 navigationController 堆栈。如果我只添加第一个控制器,这可以正常工作。但在动画应该转到第二个控制器的情况下,导航栏的标题将不会是“飞入”。相反,在动画完成之前会有一个空标题。而且,更糟糕的是,如果我用自定义按钮替换导航栏标题,则该按钮将显示在左上角,直到动画完成。这是一个相当大的显示错误。

我尝试使用多个 PushViewController 方法的解决方法,但动画看起来/感觉不正确。我希望导航以与 PushViewController 相同的方式执行动画。这里唯一的区别是,我没有添加 VC,而是立即设置整个堆栈。这里还有其他解决方法吗,或者这可以被视为框架的错误吗?我想过只对 VC2 使用 PushNavController,然后以某种方式将 VC1 插入堆栈,但这似乎不可能。

感谢您的所有提示和建议。 :-)

技术数据:我使用的是 iOS 4.2,针对 4.0 进行编译。

I'm having a problem with an iPhone App using UINavigationController. When I'm using pushNavigationController, it works fine. The iPhone does its animation while switching to the next ViewController. But when using an array of ViewControllers and the setViewControllers method, it has a glitch in the animation which can grow into a clearly visible animation bug.

The following snippet is called in the root ViewController. Depending on a condition it should either switch to ViewController1, or it should directly go to ViewController2. In the latter case the user can navigate back to vc1, then to the root.

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack
[viewControllers addObject:self];
// add first VC
AuthentificationViewController* authentificationViewController =
  [[[AuthentificationViewController alloc] initWithNibName:@"AuthentificationViewController" bundle:nil] autorelease];
[viewControllers addObject:authentificationViewController];

if (someCondition == YES)
{
 UserAssignmentsListViewController* userAssignmentsListViewController =
      [[[UserAssignmentsListViewController alloc] initWithNibName:@"UserAssignmentsOverviewViewController" bundle:nil] autorelease];

 [viewControllers addObject:userAssignmentsListViewController];
}

[self.navigationController
  setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];

As you can see I'll add the first and maybe the second VC to the array, finally setting the navigationController stack with animation. This works properly if I only add the first controller. But in the case where the animation should go to the 2nd controller, the navigation bar's title won't be "flying in". Instead there is an empty title until the animation is finished. And, even worse, if I replace the navbar title with a custom button, this button will be displayed in the upper left corner until the animation is finished. That's quite a displaying bug.

I tried to use a workaround with multiple pushViewController methods, but the animation doesn't look / feel right. I want the navigation to do its animation in the same way as pushViewController does. The only difference here is, that I don't add a VC but set the whole stack at once. Is there another workaround here, or could this be considered as a framework's bug? I thought about using only pushNavController for VC2, then somehow insert VC1 into the stack, but that doesn't seem possible.

Thanks for all hints and advices. :-)

Technical data: I'm using iOS 4.2, compiling for 4.0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谎言月老 2024-10-13 01:08:17

最后我找到了解决方案。错误在于,在动画完成之前,新的顶级 NavigationController 尚未初始化并正确加载。就我而言,UserAssignmentsListViewController 有一个 viewDidLoad 方法,在动画完成之前不会调用该方法,但它设置导航标题(此处:UIButton)。因此动画失败了。

解决方案是在将视图控制器推送到堆栈时引用已初始化的视图控制器。因此,在某处初始化我们的顶级 VC:

// initialize our top-level controller
ViewController* viewController2 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];

然后,当将两个或多个 VC 推入堆栈时,顶级 VC 已经初始化并且动画可以工作(按照我最初问题中的示例):

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack, too
[viewControllers addObject:self];

ViewController* viewController1 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];
[viewControllers addObject:viewController1];

if (someCondition == YES)
{
    [viewControllers addObject:viewController2];
}

[self.navigationController
    setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];

Finally I found the solution. The mistake was that the new top-level NavigationController has not been initialized and loaded properly until the animation is done. In my case, UserAssignmentsListViewController has a viewDidLoad method that will not be called until animation is done, but it sets the navigation title (here: a UIButton). Therefore the animation fails.

The solution is to refer to an already initialized view controller when it comes to pushing it to the stack. So initialize our top-level VC somewhere:

// initialize our top-level controller
ViewController* viewController2 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];

Then when pushing two or more VCs to the stack, the top level one is already initialized and the animation works (following the example from my original question):

NSMutableArray* viewControllers = [NSMutableArray arrayWithCapacity:2];
// put us on the stack, too
[viewControllers addObject:self];

ViewController* viewController1 = [[[ViewController alloc]
    initWithNibName:@"ViewController" bundle:nil] autorelease];
[viewControllers addObject:viewController1];

if (someCondition == YES)
{
    [viewControllers addObject:viewController2];
}

[self.navigationController
    setViewControllers:[NSArray arrayWithArray:viewControllers] animated:YES];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文