一:UIViewController模態跳轉 知識點1: a: 在官方文檔中,建議這兩者之間通過delegate實現交互。例如使用UIImagePickerController從系統相冊選取照片或者拍照,imagePickerController和彈出它的VC之間就通過UIImagePickerCo ...
一:UIViewController模態跳轉
//展示模態視圖 - (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0); //關閉模態視圖 - (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0); //只到IOS6 - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0); //只到IOS6 - (void)dismissModalViewControllerAnimated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);
知識點1:
a: 在官方文檔中,建議這兩者之間通過delegate實現交互。例如使用UIImagePickerController從系統相冊選取照片或者拍照,imagePickerController和彈出它的VC之間就通過UIImagePickerControllerDelegate實現交互的。
b: 控制器的中的只讀屬性:presentedViewController和presentingViewController,他們分別就是被present的控制器和正在presenting的控制器。
c: Modal的效果:預設是新控制器從屏幕的最底部往上鑽,直到蓋住之前的控制器為止。但可以通過自定義轉場來改變展現view的動畫,大小,位置,是否移除跳轉之前的view.這個效果可以用來模擬ipad特有的Popover彈出框。
d: 需要註意的是,預設他的實現過程是移除跳轉之前的控制器的view,並將新的控制器的view展示,但跳轉之前的控制器並沒有被釋放,而是被強引用這的。區別於導航控制器的push。
e: 通過 dismissViewControllerAnimated 來返回前一個界面的
知識點2:例如在當前A控制器利用模態跳轉到另一個B控制器
1.當前A控制器,跳轉代碼 RecipeAddViewController *addController = [[RecipeAddViewController alloc] init]; addController.modalPresentationStyle = UIModalPresentationFullScreen; addController.transitionStyle = UIModalTransitionStyleCoverVertical; [self presentViewController:addController animated:YES completion: nil]; 2.返回當前A控制器,在剛纔跳到的B控制器中,加上返回代碼 [self dismissViewControllerAnimated:YES completion:NULL];
知識點3:兩個重要的枚舉對象
//彈出時的動畫風格 typedef NS_ENUM(NSInteger, UIModalTransitionStyle) { UIModalTransitionStyleCoverVertical = 0, //從底部滑入 UIModalTransitionStyleFlipHorizontal, //水平翻轉進入 UIModalTransitionStyleCrossDissolve, //交叉溶解 UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2), //翻頁 }; //彈出風格 typedef NS_ENUM(NSInteger, UIModalPresentationStyle) { UIModalPresentationFullScreen = 0, //代表彈出VC時,VC充滿全屏 UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2), //VC的高度和當前屏幕高度相同,寬度和豎屏模式下屏幕寬度相同,剩餘未覆蓋區域將會變暗並阻止用戶點擊.這種彈出模式下,豎屏時跟UIModalPresentationFullScreen的效果一樣,橫屏時候兩邊則會留下變暗的區域; UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2), //VC的高度和寬度均會小於屏幕尺寸,VC居中顯示,四周留下變暗區域; UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2), //VC的彈出方式和彈出VC的VC的父VC的方式相同 //自定義轉場 模態轉場 需要代理實現 UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0), UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0), UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0), //告訴Presentation控制器忽視緊湊環境並繼續使用前面的Presentation風格 UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1, };
二:導航控制器UINavigationController跳轉
//推出界面 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; //返回 將棧頂的控制器移除 - (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated; //指定返回跳到詳細的哪一個上 回到指定的子控制器 - (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; //返回到最頂級 回到根控制器(棧底控制器) - (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
知識點1:popToViewController用法
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] animated:YES]; 或 UIViewController *popCtl; for (UIViewController *ctl in self.navigationController.viewControllers) { if ([ctl isKindOfClass:[MyViewController class]]) { popCtl = ctl; break; } } if (popCtl) { [self.navigationController popToViewController:popCtl animated:YES]; }
知識點2:iOS解決使用模態視圖 導致無法pushViewController
模態視圖預設從界面底部滑出並占據整個界面,並短暫地顯示與之前不同的界面,直到用戶完成某項操作。模態視圖完成和程式主功能有關係的獨立任務,尤其適合於主功能界面中欠缺的多級子任務。例如撰寫新郵件時的模態視圖.
例如:
當登錄界面的作為模態視圖的話. 當我們離開當前界用presentViewController彈出登錄界面的話..就會導致在登錄界面這個模態視圖中視圖間的跳轉會失效. 這是由於模態視圖其實是不同於導航控制器的新的視圖, 並且只有將這個視圖處理完成後才能回到原來的視圖. 模態視圖就相當於死衚衕 進入就必須原路返回, 也就是不可以在模態視圖中執行頁面跳轉.
也就是模態中無法獲取導航控制器 表現在代碼里則:self.navigationController是空的,哪如何讓模態中的self.navigationController不空呢, 也就很簡單了, 只需要將登錄這個視圖控制器封裝成navigationController 彈出來, 而這個模態只作為這個navigationController的rootViewController即可
UINavigationController* navi = [[UINavigationController alloc] initWithRootViewController:loginVC];
[self.navigationController presentViewController:navi animated:YES completion:nil];
然後, 在這個模態中視圖的跳轉就可以有我們傳過來的這個導航控制器完成了,表現在代碼;則:self.navigationController是存在的. 如果再想跳轉就可以用pushViewController了;因為包裝了一層navigationController這個'模態'會有導航欄 自行隱藏即可
退出模態視圖:
[self dismissViewControllerAnimated:YES completion:nil];
知識點3:解決使用[self.navigationController pushViewController:VC animated:YES]; push卡頓
UIViewController *vc = [UIViewController new]; [self.navigationController pushViewController:vc animated:YES]; 上述代碼推出界面會卡頓 解決辦法: UIViewController *vc = [UIViewController new]; vc.view.backgroundColor = [UIColor 推出時你想要的控制器View的顏色]