将新VC推送到navigationController似乎没有任何效果

时间:2015-04-01 07:58:59

标签: ios

这个问题听起来很基本,但我不明白我在忽视什么。

我正在尝试将新的视图控制器推入导航控制器,但topViewController仍然不受影响。

#import "TNPViewController.h"
@interface TNCViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

@implementation TNCViewController

-(void)userDidSelectNewsNotification:(NSNotification*)note

{

    TNPViewController *nextViewController = [[TNPViewController alloc] init];

    [[self navigationController] pushViewController:nextViewController animated:YES];

    UIViewController *test = [[self navigationController] topViewController];

}

测试显示TNCViewController的实例而不是TNPViewController。这怎么可能?

更新

感谢大家的参与。指示通知的方法名称是红色鲱鱼。我发现了这个问题,正如斯图尔特之前提到过的,但后来被删除了。 (由于我的声望得分很高,我仍然可以看到他删除的帖子。)

我最初的单元测试是这样的:

-(void)testSelectingNewsPushesNewViewController
{
    [viewController userDidSelectNewsNotification:nil];
    UIViewController *currentTopVC = navController.topViewController;
    XCTAssertFalse([currentTopVC isEqual:viewController], @"New viewcontroller should be pushed onto the stack.");
    XCTAssertTrue([currentTopVC isKindOfClass:[TNPViewController class]], @"New vc should be a TNPViewController");
}

它失败了。然后我设置了一个断点并尝试了上面的test实例,它仍然显示错误的topviewcontroller。

如果我改变

,至少单元测试有效
[[self navigationController] pushViewController:nextViewController animated:YES];

[[self navigationController] pushViewController:nextViewController animated:NO];

更好的解决方案是使用ANIMATED常量进行单元测试以禁用动画。

2 个答案:

答案 0 :(得分:0)

这并没有真正回答您关于为什么您的navigationController没有推送您的VC的问题。但这是关于另一种可能方法的建议。

您可以在故事板上添加新的VC,并在激活userDidSelectNewsNotification方法时激活segue。然后根据VC中的事件相应地更改信息,特别是因为您每次都在初始化它。

答案 1 :(得分:0)

这在黑暗中是一种刺痛,但如果没有更多信息,这个问题很难诊断出来。

我看到你正在尝试推送新的视图控制器以响应通知。你确定这个通知是在主线程上处理的吗?当不在主线程上执行时,诸如推送新视图控制器之类的UI方法将失败(或至少表现得不可预测)。这也可能在某种程度上解释topViewController返回意外视图控制器实例的奇怪行为。*

理想情况下,您应该保证这些通知会在主线程上发布,因此它们将在同一个线程上接收。如果您不能保证这一点(例如,如果您不负责在代码中的其他位置发布通知),那么您应该将任何与UI相关的代码分发给主线程:

- (void)userDidSelectNewsNotification:(NSNotification *)note
{
    dispatch_async(dispatch_get_main_queue(), ^{
        TNPViewController *nextViewController = [[TNPViewController alloc] initWithNibName:@"TNPViewController" bundle:nil];
        [self.navigationController pushViewController:nextViewController animated:YES];
    });
}

此外,您似乎没有使用指定的初始化程序初始化TNPViewController(除非您的子类中覆盖init并从那里调用initWithNibName:bundle:)。我不希望这会导致转换完全失败,但可能导致您的视图控制器未正确初始化。

一般情况下,你可能会更好地在故事板中创建视图控制器并使用segue来执行导航过渡,正如@Joze在他的回答中所建议的那样。您仍然可以使用performSegueWithIdentifier:在代码中启动这些故事板段(例如,响应您的通知),但同样,请务必在主线程上执行此操作。有关此方法的详细信息,请参阅Using View Controllers in Your App


*我最初写了一个答案,试图将意外的topViewController值解释为延迟动画过渡的结果。虽然动画转换确实是延迟的,但这并不会阻止topViewController立即设置到新的视图控制器。