iOS常用的轉(zhuǎn)場(chǎng)方式包括push,Modal等
本文介紹自定義Modal轉(zhuǎn)場(chǎng)動(dòng)畫(huà)來(lái)實(shí)現(xiàn)展示小菜單功能
效果圖如下:

功能由四個(gè)類(lèi)組成,分別是:
ViewController: 根控制器
HXPopoverAnimator: 自定義Modal動(dòng)畫(huà)管理者
HXJumpViewController: 要彈出的控制器(小菜單)
HXPresentationController:管理彈出小菜單HXJumpViewControllergit
github代碼:https://github.com/huberyhx/HXCustomModal.git
-
首先是主控制器界面ViewController
控制器非常簡(jiǎn)單,設(shè)置導(dǎo)航條的titleView后監(jiān)聽(tīng)titleView的點(diǎn)擊彈出jumpVc
jumpVc是將要Modal出來(lái)的控制器
HXPopoverAnimator是自定義用來(lái)管理轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi),我會(huì)在下面介紹
需要注意的是這句:jumpVc.modalPresentationStyle = UIModalPresentationCustom;
這句的作用是讓新控制器Modal出來(lái)之后新控制器下面的舊控制器依然顯示
如果不設(shè)置是不顯示的
因?yàn)槲覀冃翸odal出來(lái)的控制器是一個(gè)菜單,他并不是全屏顯示
所以如果不讓舊控制器顯示,后果將不堪設(shè)想….
我們平時(shí)正常的Modal展示出的控制器都是占據(jù)整個(gè)屏幕所以舊控制器就算不顯示也不會(huì)有影響
彈出后效果圖:

-(void)setUpTitleView{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"菜單" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.titleView = btn;
}
-(void)btnClick{
//創(chuàng)建彈出的控制器
HXJumpViewController *jumpVc = [[HXJumpViewController alloc]init];
//設(shè)置modal的樣式 默認(rèn)是UIModalPresentationNone:該控制器后面的控制器不會(huì)顯示
jumpVc.modalPresentationStyle = UIModalPresentationCustom;
//設(shè)置彈出View的frame 是自定義的屬性
self.popoverAnimator.presentFrame = CGRectMake(100, 55, 180, 250);
//設(shè)置轉(zhuǎn)場(chǎng)代理transitioningDelegate來(lái)實(shí)現(xiàn)動(dòng)畫(huà)
jumpVc.transitioningDelegate = self.popoverAnimator;
[self presentViewController:jumpVc animated:YES completion:nil];
}
//懶加載
//這里的popoverAnimator一定要是強(qiáng)引用
//不然等btnClick 執(zhí)行結(jié)束后 popoverAnimator銷(xiāo)毀了,就不會(huì)執(zhí)行popoverAnimator中定義的dismiss代理方法,我就被坑了...
-(HXPopoverAnimator *)popoverAnimator{
if (!_popoverAnimator) {
_popoverAnimator = [[HXPopoverAnimator alloc]init];
}
return _popoverAnimator;
}
-
然后是比較簡(jiǎn)單的HXPresentationController:
Modal的實(shí)現(xiàn)原理是:把將要彈出控制器的View塞進(jìn)UIPresentationController里面彈出
所以自定義Modal就要自己控制UIPresentationController要做的工作
UIPresentationController做的很簡(jiǎn)單,只做兩件事:
1:添加手勢(shì)View監(jiān)聽(tīng)點(diǎn)擊dismiss自己
2:設(shè)置彈出View的Frame效果圖可參考上圖
代碼如下:
-(void)containerViewWillLayoutSubviews{
[super containerViewWillLayoutSubviews];
//在這里設(shè)置彈出View的Frame
self.presentedView.frame = self.presentFrame;
//添加手勢(shì)View
[self.containerView insertSubview:self.maskView atIndex:0];
}
-(void)tapGes{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
//懶加載背景View
-(UIView *)maskView{
if (!_maskView) {
_maskView = [[UIView alloc]init];
_maskView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.2];
_maskView.frame = self.containerView.bounds;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGes)];
[_maskView addGestureRecognizer:tap];
}
return _maskView;
}
-
最后是HXPopoverAnimator:
HXPopoverAnimator是繼承NSObject
并且遵循UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning協(xié)議的類(lèi)
用來(lái)管理Modal動(dòng)畫(huà)
這個(gè)類(lèi)的代碼較多,就不在文章里粘貼了,請(qǐng)下載demo看吧
demo中有詳細(xì)的代碼注釋
demo地址在上面??
也可以移步博客:
http://www.itcyz.cn/ios%E8%87%AA%E5%AE%9A%E4%B9%89%E8%BD%AC%E5%9C%BA%E5%8A%A8%E7%94%BB/
感謝閱讀
你的支持是我寫(xiě)作的唯一動(dòng)力