今天劉國斌帶著學習了瀏覽列控制項, UINavigationController,UITabbarController,這兩個控制項有類似的地方, UINavigationController可以翻譯為導航控制器,在iOS裡經常用到。UINavigationController是IOS編程中的一個view controller的容器,通過棧管理viewControllers,每一次push操作都將在棧頂添加一個view controller,然後通過pop將該棧最頂端的controller移除。 我們在工程中,通常會在controller中執行 [self.navigationController popViewControllerAnimated:NO];來移除棧頂controller。 假設現在有UIViewController的子類對象,A、B、C、D。 //將A控制器設定為根控制器 UINavigationController *myFirstCtrl = [[UINavigationController alloc] initWithRootViewController:myFirstCtrl]; self.window.rootViewController = m_firstCtrl; //在A控制器中,push B控制器 [self.navigationController pushViewController:B animated:NO]; //在B控制器中,push C控制器 [self.navigationController pushViewController:B animated:NO]; //在C控制器中,push D控制器 [self.navigationController pushViewController:B animated:NO]; 則此時A控制器的棧中,有四個元素,我們認為在B、C、D中都沒有pop操作,此時,在A控制器中,執行[self.navigationController popViewControllerAnimated:NO];則是將D控制器從棧中移除,並非我們理解的將A控制器本身移除。同樣,再次執行時,是將C控制器移除。 以前,我都是認為移除自身的,今天跟同事進行討論後,寫了一個demo驗證了一下,才知道了真相。所以,寫出來跟大家分享一下,也許大家已經知道了,聞道有先後,雖然我可能知道的遲了點,但是我還是很高興分享出來,給還不知道的朋友
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 建立一個視圖控制器 RootViewController *vc0 = [RootViewController new]; // 建立導航控制器, 並且設定導航控制器的根視圖(最底層視圖) UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc0]; // 因為當前視圖沒有被導航所管理, 所以無法使用 push 方法跳轉, 只能使用 present 方法跳轉 [self presentViewController:navController animated:YES completion:nil]; // self.navigationController 屬性 // 若當前的視圖控制器已經被導航控制器所管理, 則該屬性有作用 // 若當前的視圖控制器沒有被導航控制器所管理, 則該屬性沒有用(值為 nil) // [self.navigationController pushViewController:navController animated:YES]; } 。 |