iOS轉(zhuǎn)場(chǎng)動(dòng)畫(huà)-自定義轉(zhuǎn)場(chǎng)

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


modal.gif

功能由四個(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ì)有影響
彈出后效果圖:


結(jié)構(gòu)圖.jpeg
-(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)力

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容