在iOS開發(fā)中,比較常用的切換視圖的方式主要有以下幾種:
1.入棧出棧方式 push、pop
使用舉例(ViewController假設(shè)為需要跳轉(zhuǎn)的控制器):
[self.navigationController pushViewController:ViewController animated:YES]; //入棧,跳轉(zhuǎn)到指定控制器視圖
[self.navigationController popViewControllerAnimated:YES]; //彈棧锐峭,返回到前一個(gè)視圖
[self.navigationController popToViewController:ViewController animated:YES]; //彈棧 返回指定控制器所在視圖
[self.navigationController popToRootViewControllerAnimated:YES]; //彈棧 返回根控制器視圖
2.模態(tài) modal
使用舉例(ViewController假設(shè)為需要跳轉(zhuǎn)的控制器):
[self presentViewController:ViewController animated:YES completion:nil]; //跳轉(zhuǎn)到ViewController所在視圖
[self dismissModalViewControllerAnimated:YES]; //退出當(dāng)前視圖
3. 切換window的rootViewController
使用舉例(ViewController假設(shè)為需要跳轉(zhuǎn)的控制器):
UIWindow *window = [UIApplication sharedApplication].keyWindow; //獲得主窗口
window.rootViewController = [[ViewController alloc] init]; //將主窗口的根視圖設(shè)置為當(dāng)前控制器
4. 將另一個(gè)控制器的視圖添加為當(dāng)前控制器視圖的子視圖
[self.view addSubview: ViewController.View]; //實(shí)現(xiàn)復(fù)雜界面的時(shí)候常用
簡要介紹下各種方式的優(yōu)點(diǎn)和不足:
- push、pop方式
- 優(yōu)點(diǎn):控制器切換是可逆的,且原始圖不會(huì)銷毀
- 缺點(diǎn):依賴于UINavigationController盈电,故需要有一個(gè)導(dǎo)航控制器,與某些界面不需要導(dǎo)航控制器有可能會(huì)沖突
push操作是可逆的杯活,即控制器的切換是可逆的匆帚。
- modal
- 優(yōu)點(diǎn):控制器切換是可逆的,且原始圖不會(huì)銷毀
- 缺點(diǎn):跳轉(zhuǎn)沒有push方式自由旁钧,dismiss方式只能按順序返回吸重,不能跳躍互拾, 從前一個(gè)modal到后一個(gè)時(shí)候,前一個(gè)控制器不會(huì)消失嚎幸,一直在內(nèi)存中
這里說明一下控制器的兩個(gè)可能很多人都沒注意的兩個(gè)只讀屬性:presentedViewController和presentingViewController颜矿,他們分別是被present的控制器和正在presenting的控制器。
這兩個(gè)屬性嫉晶,在有些時(shí)候骑疆,用起來是很方便的。比如說替废,現(xiàn)在有個(gè)C界面箍铭,C界面被顯示出來,可能有兩種情況椎镣,一是modal出來的诈火,另外一種是push出來的,這時(shí)候就可以通過當(dāng)前界面對象的presentingViewController屬性來判斷到底屬于哪種情況衣陶,如果是nil柄瑰,表示是UINavigationController對象push過來的,如果不是則是modal過來的剪况。
- 切換window的rootViewController
- 優(yōu)點(diǎn):跳轉(zhuǎn)直接迅速教沾,而且可以銷毀前一個(gè)控制器,因?yàn)閷indow的強(qiáng)引用改為當(dāng)前控制器译断,故前一個(gè)控制器會(huì)消失(ARC環(huán)境)
- 缺點(diǎn):視圖跳轉(zhuǎn)不可逆
- 將一個(gè)控制器的視圖添加到當(dāng)前視圖上面
- 優(yōu)點(diǎn):通過一個(gè)控制器將另一控制器設(shè)置為屬性授翻,自由讀取其他控制器中的視圖從而能夠?qū)崿F(xiàn)復(fù)雜UI界面
- 缺點(diǎn):復(fù)雜,多數(shù)場合不適用
列表比較如下:
比較項(xiàng)目 | push孙咪、pop | modal | 切換窗口的根控制器 | 添加子視圖 |
---|---|---|---|---|
銷毀源視圖 | 否 | 否 | 是 | 否 |
使用場合 | 有導(dǎo)航控制器堪唐,需要能夠返回前一個(gè)視圖的情況 | 沒有導(dǎo)航控制器的跳轉(zhuǎn),能返回前一個(gè)視圖 | 版本新特性或者不需要保留前一個(gè)控制器的情況 | 需要實(shí)現(xiàn)復(fù)雜界面的情況 |
是否有導(dǎo)航控制器 | 是 | 否 | 否 | 否 |
我們這里再說一下針對系統(tǒng)的這兩種視圖切換方式,都有哪些最基本的動(dòng)畫呢?
首先是模態(tài)切換
//常規(guī)模態(tài)切換
push.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentViewController:push animated:YES completion:nil];
/*
下面是四種具體效果
UIModalTransitionStyleCoverVertical=0, //默認(rèn)方式翎蹈,豎向上推
UIModalTransitionStyleFlipHorizontal, //水平反轉(zhuǎn)
UIModalTransitionStyleCrossDissolve,//隱出隱現(xiàn)
UIModalTransitionStylePartialCurl,//部分翻頁效果
*/
//當(dāng)你想要使用自定義模態(tài)切換的時(shí)候,這一行代碼是必須的
push.modalPresentationStyle = UIModalPresentationCustom;
當(dāng)使用入棧出棧的方式切換的時(shí)候
PushViewController *push = [[PushViewController alloc]init];
//添加Animation
[self.navigationController.view.layer addAnimation:[self pushAnimation] forKey:nil];
[self.navigationController pushViewController:push animated:YES];
//這里是Animation動(dòng)畫的方法
- (CATransition *)pushAnimation{
//創(chuàng)建動(dòng)畫
CATransition* transition = [CATransition animation];
//設(shè)置持續(xù)時(shí)間
transition.duration = 0.8;
//設(shè)置時(shí)間函數(shù)
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
/*私有API
cube 立方體效果
pageCurl 向上翻一頁
pageUnCurl 向下翻一頁
rippleEffect 水滴波動(dòng)效果
suckEffect 變成小布?jí)K飛走的感覺
oglFlip 上下翻轉(zhuǎn)
cameraIrisHollowClose 相機(jī)鏡頭關(guān)閉效果
cameraIrisHollowOpen 相機(jī)鏡頭打開效果
*/
//使用私有API 設(shè)置動(dòng)畫類型
transition.type = @"cube";
//或者使用系統(tǒng)共有API
//transition.type = kCATransitionFade;
//下面四個(gè)是系統(tǒng)共有的API
//kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, kCATransitionFade
//設(shè)置切換方向
transition.subtype = kCATransitionFromBottom;
//切換方向有以下四種方式:kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
//還可以設(shè)置代理 實(shí)現(xiàn)代理方法來監(jiān)聽動(dòng)畫已經(jīng)開始和已經(jīng)結(jié)束
transition.delegate = self;
return transition;
}
還可以用animation轉(zhuǎn)場動(dòng)畫
//方式1
[UIView transitionWithView:[UIApplication sharedApplication].keyWindow duration:0.5f options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[UIApplication sharedApplication].keyWindow.rootViewController = [[ChatViewController alloc]init];
[UIView setAnimationsEnabled:oldState];
} completion:^(BOOL finished) {
}];
//方式2
[UIView transitionFromView:self.view toView:chatVC.view duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
}];