popViewControllerAnimated:YES不起作用

时间:2014-11-13 21:16:46

标签: ios uinavigationcontroller viewcontroller

我正在编写单元测试,我发现popViewControllerAnimated:YES不起作用。

(void)testNavi {
  UINavigationController *navi = [[UINavigationController alloc] init];
  UIViewController *controllerA = [[UIViewController alloc] initWithNibName:nil bundle:nil];
  UIViewController *controllerB = [[UIViewController alloc] initWithNibName:nil bundle:nil];
  [navi pushViewController:controllerA animated:NO];
  [navi pushViewController:controllerB animated:NO];
  [navi popViewControllerAnimated:YES];
  XCTAssertEqual(navi.topViewController, controllerA);
}

如果我将[navi popViewControllerAnimated:YES]更改为[navi popViewControllerAnimated:NO],它可以正常工作。我不知道为什么。

3 个答案:

答案 0 :(得分:0)

您最好在创建视图后调用popViewControllerAnimated。所以你可以创建NavigationController的子类并像这样实现它。

- (void)init {
   self = [super init];
   if (self) {
      UIViewController *controllerA = [[UIViewController alloc] initWithNibName:nil bundle:nil];
      UIViewController *controllerB = [[UIViewController alloc] initWithNibName:nil bundle:nil];
      self.viewControllers = @[controllerA, controllerB];
   }
   return self;
}

- (void)viewWillAppear {
   [self popViewControllerAnimated:YES];
}

答案 1 :(得分:0)

这是因为动画在另一个线程上异步发生。弹出视图控制器的动画需要花费少量时间,但测试断言是在动画完成之前进行的,因此topViewController尚未更改。

测试它的最佳方法是模拟UINavigationController并验证是否popViewController:YES被调用。

答案 2 :(得分:0)

在推动动画时,我遇到了类似的问题pushViewController

我能够通过将我的断言包含在matt的这个方便的delay函数中来解决这个问题。

在测试中引入延迟时,必须使用期望来确保检查断言。否则,测试在延迟代码执行之前完成,导致通过的测试没有检查你的断言!

// code to push the view controller goes here...

// set up the expectation
let expectation = expectationWithDescription("anything you want")

// now, assert something about the navigation controller 
// after waiting 1/10th second for the animation to finish
delay (0.1) {

    // for example: Navigation controller should have the 
    // expected number of view controllers
    XCTAssertEqual(1, navigationController.viewControllers.count)

    // if we get this far, then assertions passed and we must
    // fulfill expectations to pass the test
    expectation.fulfill()
}

// wait longer than the delay value, so the code in the delay closure
// has time to finish
waitForExpectationsWithTimeout(0.2, handler: nil)