一:UIViewController模態(tài)跳轉(zhuǎn)
復(fù)制代碼
//展示模態(tài)視圖
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
//關(guān)閉模態(tài)視圖
- (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);
復(fù)制代碼
知識(shí)點(diǎn)1:
a: 在官方文檔中解阅,建議這兩者之間通過delegate實(shí)現(xiàn)交互界赔。例如使用UIImagePickerController從系統(tǒng)相冊(cè)選取照片或者拍照蒜撮,imagePickerController和彈出它的VC之間就通過UIImagePickerControllerDelegate實(shí)現(xiàn)交互的。
b: 控制器的中的只讀屬性:presentedViewController和presentingViewController演怎,他們分別就是被present的控制器和正在presenting的控制器。
c: Modal的效果:默認(rèn)是新控制器從屏幕的最底部往上鉆健民,直到蓋住之前的控制器為止憾朴。但可以通過自定義轉(zhuǎn)場(chǎng)來改變展現(xiàn)view的動(dòng)畫,大小热幔,位置乐设,是否移除跳轉(zhuǎn)之前的view.這個(gè)效果可以用來模擬ipad特有的Popover彈出框。
d: 需要注意的是绎巨,默認(rèn)他的實(shí)現(xiàn)過程是移除跳轉(zhuǎn)之前的控制器的view近尚,并將新的控制器的view展示,但跳轉(zhuǎn)之前的控制器并沒有被釋放场勤,而是被強(qiáng)引用這的戈锻。區(qū)別于導(dǎo)航控制器的push。
e: 通過 dismissViewControllerAnimated 來返回前一個(gè)界面的
知識(shí)點(diǎn)2:例如在當(dāng)前A控制器利用模態(tài)跳轉(zhuǎn)到另一個(gè)B控制器
復(fù)制代碼
1.當(dāng)前A控制器和媳,跳轉(zhuǎn)代碼
RecipeAddViewController *addController = [[RecipeAddViewController alloc] init];
addController.modalPresentationStyle = UIModalPresentationFullScreen;
addController.transitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:addController animated:YES completion: nil];
2.返回當(dāng)前A控制器格遭,在剛才跳到的B控制器中,加上返回代碼
[self dismissViewControllerAnimated:YES completion:NULL];
復(fù)制代碼
知識(shí)點(diǎn)3:兩個(gè)重要的枚舉對(duì)象
復(fù)制代碼
//彈出時(shí)的動(dòng)畫風(fēng)格
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
UIModalTransitionStyleCoverVertical = 0,? //從底部滑入
UIModalTransitionStyleFlipHorizontal,? //水平翻轉(zhuǎn)進(jìn)入
UIModalTransitionStyleCrossDissolve,? //交叉溶解
UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2),? //翻頁
};
//彈出風(fēng)格
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,? //代表彈出VC時(shí)窗价,VC充滿全屏
UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),? //VC的高度和當(dāng)前屏幕高度相同如庭,寬度和豎屏模式下屏幕寬度相同叹卷,剩余未覆蓋區(qū)域?qū)?huì)變暗并阻止用戶點(diǎn)擊.這種彈出模式下撼港,豎屏?xí)r跟UIModalPresentationFullScreen的效果一樣坪它,橫屏?xí)r候兩邊則會(huì)留下變暗的區(qū)域;
UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),? //VC的高度和寬度均會(huì)小于屏幕尺寸帝牡,VC居中顯示往毡,四周留下變暗區(qū)域;
UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),? //VC的彈出方式和彈出VC的VC的父VC的方式相同
//自定義轉(zhuǎn)場(chǎng) 模態(tài)轉(zhuǎn)場(chǎng) 需要代理實(shí)現(xiàn)
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控制器忽視緊湊環(huán)境并繼續(xù)使用前面的Presentation風(fēng)格
UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,
};
復(fù)制代碼
二:導(dǎo)航控制器UINavigationController跳轉(zhuǎn)
復(fù)制代碼
//推出界面
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
//返回 將棧頂?shù)目刂破饕瞥?/p>
- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;
//指定返回跳到詳細(xì)的哪一個(gè)上 回到指定的子控制器
- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
//返回到最頂級(jí) 回到根控制器(棧底控制器)
- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
復(fù)制代碼
知識(shí)點(diǎn)1:popToViewController用法
復(fù)制代碼
[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];
}
復(fù)制代碼
知識(shí)點(diǎn)2:iOS解決使用模態(tài)視圖 導(dǎo)致無法pushViewController
模態(tài)視圖默認(rèn)從界面底部滑出并占據(jù)整個(gè)界面靶溜,并短暫地顯示與之前不同的界面开瞭,直到用戶完成某項(xiàng)操作。模態(tài)視圖完成和程序主功能有關(guān)系的獨(dú)立任務(wù)罩息,尤其適合于主功能界面中欠缺的多級(jí)子任務(wù)嗤详。例如撰寫新郵件時(shí)的模態(tài)視圖.
例如:
當(dāng)?shù)卿浗缑娴淖鳛槟B(tài)視圖的話. 當(dāng)我們離開當(dāng)前界用presentViewController彈出登錄界面的話..就會(huì)導(dǎo)致在登錄界面這個(gè)模態(tài)視圖中視圖間的跳轉(zhuǎn)會(huì)失效. 這是由于模態(tài)視圖其實(shí)是不同于導(dǎo)航控制器的新的視圖, 并且只有將這個(gè)視圖處理完成后才能回到原來的視圖. 模態(tài)視圖就相當(dāng)于死胡同 進(jìn)入就必須原路返回, 也就是不可以在模態(tài)視圖中執(zhí)行頁面跳轉(zhuǎn).
也就是模態(tài)中無法獲取導(dǎo)航控制器 表現(xiàn)在代碼里則:self.navigationController是空的,哪如何讓模態(tài)中的self.navigationController不空呢, 也就很簡(jiǎn)單了, 只需要將登錄這個(gè)視圖控制器封裝成navigationController 彈出來, 而這個(gè)模態(tài)只作為這個(gè)navigationController的rootViewController即可
UINavigationController* navi = [[UINavigationController alloc] initWithRootViewController:loginVC];
[self.navigationController presentViewController:navi animated:YES completion:nil];
然后, 在這個(gè)模態(tài)中視圖的跳轉(zhuǎn)就可以有我們傳過來的這個(gè)導(dǎo)航控制器完成了,表現(xiàn)在代碼;則:self.navigationController是存在的. 如果再想跳轉(zhuǎn)就可以用pushViewController了瓷炮;因?yàn)榘b了一層navigationController這個(gè)'模態(tài)'會(huì)有導(dǎo)航欄 自行隱藏即可
退出模態(tài)視圖:
[self dismissViewControllerAnimated:YES completion:nil];
知識(shí)點(diǎn)3:解決使用[self.navigationController pushViewController:VC animated:YES]; push卡頓
復(fù)制代碼
UIViewController *vc = [UIViewController new];
[self.navigationController pushViewController:vc animated:YES];
上述代碼推出界面會(huì)卡頓
解決辦法:
UIViewController *vc = [UIViewController new];
vc.view.backgroundColor = [UIColor 推出時(shí)你想要的控制器View的顏色]