2015-04-01 38 views
1

這個問題聽起來很基本,但我不明白我忽略了什麼。將一個新的VC推入導航控制器似乎沒有效果

我試圖將新的視圖控制器推入導航控制器,但是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的實例。這怎麼可能?

UPDATE

感謝大家的參與。指示通知的方法名稱是紅色鯡魚。我發現這個問題,正如斯圖爾特之前提到的,但後來被刪除。 (由於我的信譽得分很高,我仍然可以看到他刪除的帖子)。

我最初的單元測試是這樣的:

-(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]; 

更好的解決方案是使用一個動畫常數單元測試禁用動畫單元測試工作。

+2

推控制器需要一些時間。當你試圖閱讀頂級控制器時,它還沒有完成 – oxigen 2015-04-01 08:07:53

+0

簡單地將下一個視圖控制器添加到故事板並將其傳遞給segger會不會更明智?然後相應地更改內容?而不是初始化每一個新的TNPViewController ... – Joze 2015-04-01 08:08:55

+0

檢查這個'[self navigationController] .title = @「Some Title」;'如果這不起作用,它應該證明你的用戶界面實際上有一些其他導航VC不等於'[self navigationController]' – 2015-04-01 08:25:43

回答

0

這並不真正回答你的問題,爲什麼你的navigationController不推動你的VC。但這是對另一種可能方法的建議。

您可以改爲在故事板上添加一個新的VC,並在userDidSelectNewsNotification方法被激活時簡單地激活segue。然後相應地將信息更改爲VC中的事件,特別是因爲您每次都要初始化它。

+0

雖然我同意故事板可以更方便地管理應用的用戶界面,但我認爲你誤解了它們的工作原理。故事板中的視圖控制器不被重用;每次執行故事板時,都會初始化一個新內容,就像在@ Houman的程序化方法中一樣。事實上,這可能是不使用故事板的原因,因爲在代碼中,您可以存儲和重新使用難以加載的視圖控制器,而不是每次從故事板實例化一個新視圖控制器。 – Stuart 2015-04-01 08:15:22

+0

@Stuart謝謝你,是的,我一定誤解了他們的內在運作。我猜想取決於他的申請。但它仍然更容易使用和理解恕我直言。我現在看到了程序化方法的好處。如果他打算初始化它,無論如何,塞格是要走的路。 – Joze 2015-04-01 08:40:53

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:?)。我不希望這會導致轉換完全失敗,但可能導致視圖控制器未正確初始化。

通常,您可能會更好地在故事板中創建視圖控制器,並使用segues來執行導航轉換,就像@Joze在他的回答中所表明的那樣。您仍然可以在performSegueWithIdentifier:的代碼中啓動這些storyboard segues(例如回覆您的通知),但是請務必在主線程中這樣做。有關此方法的更多詳細信息,請參閱Using View Controllers in Your App


*我原來寫的答案試圖解釋意想不到topViewController價值爲遞延場動畫的結果。儘管動畫過渡是延遲的,但這並不妨礙topViewController立即被設置爲新的視圖控制器。

相關問題