前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Container ViewController自定义转场控制器。

Container ViewController自定义转场控制器。

作者头像
Charlie_W
发布2018-10-19 14:56:33
6890
发布2018-10-19 14:56:33
举报
文章被收录于专栏:Charlie's RoadCharlie's Road
前言

最近接触到新公司的老项目改版。自从来了之后一直在忙另一个项目,也没有看老项目的实现逻辑。 看到设计稿的时候,并不是普通的树形标签导航的样子。大致效果如FaceU的主页:

clipboard.png
clipboard.png

布局类似,但是功能有点不一样:

  1. 顶部左侧的按钮点击后会出现个人中心页。
  2. 顶部中间还有个按钮,点击会出现一个业务页
  3. 顶部左侧的按钮也会出现业务页。

刚看完之后,感觉这种设计真麻烦。最爱UITabBarController+UINavgationController的CP组合好像失效的。难道只能用present来实现么。

经同事指导,最后找到Container View Controllers Quickstart,才发现一种新的转场实现方式。下面就动手实践一下。

第一步,创建项目:

创建一个空的demo project,怎么创建我就不说了。其他任何选项都不用修改,run下应该有个黑色的空白页面。

打开viewController.m创建两个UIButton:

代码语言:javascript
复制
@interface ViewController ()
@property (nonatomic, strong) UIButton *leftBtn;
@property (nonatomic, strong) UIButton *rightBtn;

@end



@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.leftBtn];
    [self.view addSubview:self.rightBtn];
}
#pragma mrk - subviews
// fram随便写的,主要看效果
- (UIButton *)leftBtn {
    if (_leftBtn == nil) {
        _leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _leftBtn.frame = CGRectMake(0, 60, 100, 100);
        _leftBtn.backgroundColor = [UIColor blueColor];
        [_leftBtn addTarget:self action:@selector(leftAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _leftBtn;
}

- (UIButton *)rightBtn {
    if (_rightBtn == nil) {
        _rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _rightBtn.frame = CGRectMake(kScreenWidth - 100, 60, 100, 100);
        _rightBtn.backgroundColor = [UIColor blueColor];
        [_rightBtn addTarget:self action:@selector(rightAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _rightBtn;
}
@end

run起来,应该可以看到页面变成白色的,并且带有两个蓝色的色块。这两个色块就代表前言中顶部的左右按钮,点击左边的色块会从左边弹出一个控制器,右边的同理。

clipboard.png
clipboard.png
第二步,实现弹出控制器:

现在我们给左右按钮addTarget

代码语言:javascript
复制
- (void)leftAction {
}

- (void)rightAction {
}

并创建一个左侧的控制器TestOneViewController:

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    NSLog(@"----TestOneViewController  didload-");
}

- (void)dealloc {
    NSLog(@"----TestOneViewController dealloc--");
}

并用NSLog来监听它的生命周期。

`viewcontroller.m中引入,并添加如下属性方法:

代码语言:javascript
复制
// 记录当前是哪个vc
@property (nonatomic, strong) UIViewController *currentVC;
@property (nonatomic, strong) TestOneViewController *leftVC;

// 移除掉不活动的vc
- (void)removeInactiveVC:(UIViewController *)inActiveVC {
    if (inActiveVC) {
        [inActiveVC willMoveToParentViewController:nil];
        [UIView animateWithDuration:0.2 animations:^{
            inActiveVC.view.frame = [self dismissToFrame];
        } completion:^(BOOL finished) {
            
            [inActiveVC.view removeFromSuperview];
            [inActiveVC removeFromParentViewController];
            self.currentVC = nil;
        }];
    }
}
// currentVC的setter
- (void)setCurrentVC:(UIViewController *)currentVC {
    
    if (_currentVC == currentVC) {
        return;
    }
    [self removeInactiveVC:_currentVC];
    _currentVC = currentVC;
    [self updateActiveViewContrller];
}
// leftAction的实现
- (void)leftAction {
    self.currentVC = self.leftVC;
}

// 更新新的vc到当前试图
- (void)updateActiveViewContrller {
    if (self.currentVC) {
        [self addChildViewController:self.currentVC];
        self.currentVC.view.frame = [self dismissToFrame];
        [self.view addSubview:self.currentVC.view];
        [UIView animateWithDuration:0.2 animations:^{
            self.currentVC.view.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
        }completion:^(BOOL finished) {
            
            [self.currentVC didMoveToParentViewController:self];
        }];
        
    }
}
// leftVC的懒加载
- (TestOneViewController *)leftVC {
    if (_leftVC == nil) {
        _leftVC = [TestOneViewController new];
    }
    return _leftVC;
}

运行效果如下(找了个网页压缩了下,还给打上了水印):

clipboard.png
clipboard.png

相对应的右侧弹出的实现方式一样,只是把Frame更改下,就可以实现从右侧弹出的效果。具体代码就不贴了。

如果想回到主页,只用写个移除self.currentVC的方法,调用下就可以了。

代码语言:javascript
复制
- (void)backToMainViewController {
    [self removeInactiveVC:self.currentVC];
    
}
结束,优化。

到这,大致的实现逻辑都已经讲明了。只是代码有点乱。如果要再项目中使用,第一个ViewController就相当于我们的主页,然后再主页里写这些逻辑就会把主页弄的很臃肿。所以我们其实可可以相UITabbarController一样,写一个控制器,然后传入需要的UIViewController数组,就可以实现。这样使用起来也方便,维护也简单。具体封装就不赘述(我也封装的不太好),最终成型的代码,有兴趣的可以看下。有不妥之处请指出。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 第一步,创建项目:
      • 第二步,实现弹出控制器:
      • 结束,优化。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档