剖析Path侧边栏抽屉效果原理(抽屉效果,Path效果)

如今很多App应用,都用到了侧边栏的效果,比如网易新闻(还带有偏移缩小),今日头条(普遍这种),Path(最先应用这种抽屉效果,所以这种效果也叫Path效果),code4App上已经有很多网友写的第三方侧边栏类,大家可以直接拿来用.这里我主要的是介绍一下这种效果的实现原理,涉及了几个知识点,在其他地方也能用到.

UINavigationController和UITabBarController是2个主要的视图控制容器,都有属性viewControllers,能够很好地管理多个视图控制器.但有的时候,系统给的有很大的局限性,我们做效果,更多是基于系统UI,自定义很多的控件.就拿侧边栏效果举例,表面上看上去,它只有3个UIViewController,left-mid-right,中间的minViewController作为根控制器.其实,不是的,有4个,应该还有一个RootViewController,作为管理它们的视图控制容器,它的作用,就像UITabBarController,只做管理那3个视图控制器之用,并不参与任何子ViewController的视图,数据的操作.

这里,又要讲一下UIView和UIViewController的关系了.UIView(视图)在展示用户界面和响应用户界面交互方面起很重要的作用,我们所看到的内容,都是通过视图展示给我们的,属于MVC中的V.而UIViewController(视图控制器),保存所管理视图的引用,协调Model和View之间的数据,通常作为委托或者数据源,简而言之就是实现数据操纵的地方.为什么要讲这个呢?因为我有朋友,直接在一个RootViewController加了3个UIView,我就说他,你干嘛不用UIViewController,他说你那不是控制器嘛,又不是视图.....晕倒,每个UIViewController都有自己管理的view,直接.view不就出来了嘛.

不仅仅是侧边栏是这样,网易App主界面标签控制的内容也是这样,标签"头条"-"娱乐"-"体育"-"财经"-"科技"等等,其实每个都是对应了一个UIViewController,而不是UITableView,MVC的本意就是M和V不交互,数据的操作还是要放在controller中的,利用iOS5新出的属性addChildViewController,这样就不需要在一个controller处理所有的标签内容,而是将不同数据的处理各自对应一个viewController,一个主UIViewController用来做控制作用(额,是不是有点混乱,没关系,我在下一章会将网易标签栏对应各个内容的功能剖析出来)

@展示主要代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];

    DNWLeftViewController * leftVC = [[DNWLeftViewController alloc] init];
    //UINavigationController * leftNC = [[UINavigationController alloc] initWithRootViewController:leftVC];

    DNWRightViewController * rightVC = [[DNWRightViewController alloc] init];
    //UINavigationController * rightNC = [[UINavigationController alloc] initWithRootViewController:rightVC];

    DNWMidViewController * midVC = [[DNWMidViewController alloc] init];
    UINavigationController * midNC = [[UINavigationController alloc] initWithRootViewController:midVC];

    DNWRootViewController * rootVC = [[DNWRootViewController alloc] init];
    //UINavigationController * rootNC = [[UINavigationController alloc] initWithRootViewController:rootVC];
    rootVC.leftViewController = leftVC;
    rootVC.rightViewController = rightVC;
    rootVC.midViewController = midNC;

    self.window.rootViewController = rootVC;

    [self.window makeKeyAndVisible];
    return YES;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    /**
     *  1.加载视图的顺序,中间视图放在最后加,因为程序一开始它要显示在最上面
     *  2.所有ViewController的View如果不设置的话,默认全屏大小(标签栏展示效果的话,所有的ViewController都是标签栏以下大小)
     *  3.这里的self-->RootViewController,不要设置为导航控制器
     *  4.只做视图切换,不做其他任何数据操作
     *  5.手势切换,原理一样,自己可以加上,点击或者拖拉都想,这个我就不在这里描述了
     *
     */
    [self addChildViewController:self.leftViewController];
    [self.view addSubview:self.leftViewController.view];

    [self addChildViewController:self.rightViewController];
    [self.view addSubview:self.rightViewController.view];

    [self addChildViewController:self.midViewController];
    [self.view addSubview:_midViewController.view];

    UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
    leftButton.frame = CGRectMake(0, 20, 40, 40);
    [leftButton setTitle:@"left" forState:UIControlStateNormal];
    [leftButton addTarget:self action:@selector(didClickLeftBarButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.midViewController.view addSubview:leftButton];

    UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
    rightButton.frame = CGRectMake(280 ,20, 40, 40);
    [rightButton setTitle:@"right" forState:UIControlStateNormal];
    [rightButton addTarget:self action:@selector(didClickRightBarButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.midViewController.view addSubview:rightButton];
}

//  网易侧边栏效果
- (void)didClickLeftBarButtonAction:(UIBarButtonItem *)leftButton{

    //  用这个判断条件是为了左边视图出来后,再点击按钮能够回去
    if (self.midViewController.view.frame.origin.x == 0) {

        [UIView animateWithDuration:0.3 animations:^{
            //  ScreenWidth  ScreenHeight  屏幕实际大小宏
            self.leftViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
            //  也可以通过这种方式来实现
            //self.midViewController.view.transform = CGAffineTransformTranslate(self.midViewController.view.transform, 280,64 );
            self.midViewController.view.frame = CGRectMake(280, 64, ScreenWidth, ScreenHeight-64*2);
            self.rightViewController.view.frame = CGRectMake(280, 64, ScreenWidth, ScreenHeight-64*2);

        } completion:^(BOOL finished) {
        }];

    }else{

        [UIView animateWithDuration:0.3 animations:^{

            self.midViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
            self.rightViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);

        } completion:^(BOOL finished) {
        }];
    }

}

//  标准侧边栏效果
- (void)didClickRightBarButtonAction:(UIBarButtonItem *)rightButton{

    if (_midViewController.view.frame.origin.x == 0) {

        [UIView animateWithDuration:1.1 animations:^{

            _midViewController.view.frame = CGRectMake(-280, 0, ScreenWidth, ScreenHeight);
            _rightViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);

        } completion:^(BOOL finished) {

        }];

    }else{

        [UIView animateWithDuration:1.1 animations:^{

            _midViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
            _rightViewController.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);

        } completion:^(BOOL finished) {

        }];
    }
}

@效果图

剖析Path侧边栏抽屉效果原理(抽屉效果,Path效果)

时间: 2024-10-26 20:22:30

剖析Path侧边栏抽屉效果原理(抽屉效果,Path效果)的相关文章

各种效果原理(抽屉,多个tableView复用)

1.抽屉效果原理 添加3个UIView1,2,3到控制器上并记录属性. 添加当前view3的手势,实现手势方法(不能使用view3.transform,用frame根据偏移量计算view3的frame) 根据拖动时的偏移量来判断view2,view3谁隐藏 根据手势的几个状态来设置抽屉效果并计算view3的frame(UIGestureRecongnizerStateEnded[手指松开]) 添加点按手势复位(设置frame) 注意:当一个控制器的View添加到另一个控制器的View上,那么他的

带动画效果的抽屉菜单栏

带动画效果的抽屉菜单栏 带动画效果的抽屉菜单栏,将android L 中drawer-indicator/back-arrow移植到低版本Android系统中. 下载地址:http://www.devstore.cn/code/info/960.html 运行截图:

自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果

前言:好想义无反顾地追逐梦想 相关文章:<Android自定义控件三部曲文章索引> 从这篇开始,我将延续androidGraphics系列文章把图片相关的知识给大家讲完,这一篇先稍微进阶一下,给大家把<android Graphics(二):路径及文字>略去的quadTo(二阶贝塞尔)函数,给大家补充一下. 本篇最终将以两个例子给大家演示贝塞尔曲线的强大用途: 1.手势轨迹 利用贝塞尔曲线,我们能实现平滑的手势轨迹效果 2.水波纹效果 电池充电时,有些手机会显示水波纹效果,就是这样

Android自定义控件-Path之贝赛尔曲线和手势轨迹、水波纹效果

从这篇开始,我将延续androidGraphics系列文章把图片相关的知识给大家讲完,这一篇先稍微进阶一下,给大家把<android Graphics(二):路径及文字>略去的quadTo(二阶贝塞尔)函数,给大家补充一下. 本篇最终将以两个例子给大家演示贝塞尔曲线的强大用途: 1.手势轨迹 利用贝塞尔曲线,我们能实现平滑的手势轨迹效果 2.水波纹效果 电池充电时,有些手机会显示水波纹效果,就是这样做出来的. 废话不多说,开整吧 一.概述 在<android Graphics(二):路径

《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果

本文完全转载:http://www.cnblogs.com/Imageshop/p/3281703.html,再次仅当学习交流使用.. <Single Image Haze Removal Using Dark Channel Prior>一文中图像去雾算法的原理.实现.效果(速度可实时) 本文算法合作联系QQ: 33184777, 非诚勿扰 邮件地址:   [email protected] 最新的效果见 :http://video.sina.com.cn/v/b/124538950-125

Jquery 图片走马灯效果原理

本篇只讲解水平走马灯效果,垂直向上走马灯效果不讲解,原理一样,但是水平走马灯效果有一个小坑.待会讲解 照例先上代码: HTML: <div class="box"> <div style="width: 1000px;" id="boxdiv"> <ul> <li style="display: block;" title="清灵少女宛如梦境仙女"><a

鸽巢原理(抽屉原理)的详解

抽屉原理 百科名片 桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面放两个苹果.这一现象就是我们所说的“抽屉原理”. 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1或多于n+1个元素放到n个集合中去,其中必定至少有一个集合里有两个元素.” 抽屉原理有时也被称为鸽巢原理(“如果有五个鸽子笼,养鸽人养了6只鸽子,那么当鸽子飞回笼中后,至少有一个笼子中装有2只鸽子”).它是组合数学中一个重要的原理. 第一抽屉原理 原

wpf 模拟3D效果(和手机浏览图片效果相似)(附源码)

原文 wpf 模拟3D效果(和手机浏览图片效果相似)(附源码) pf的3D是一个很有意思的东西,类似于ps的效果,类似于电影动画的效果,因为动画的效果,(对于3D基础的摄像机,光源,之类不介绍,对于依赖属性也不介绍.),个人认为,依赖属性这个东西,有百分之五十是为了3D而存在.(自己写的类似于demo的东西)先上图,无图无真相这是demo的整个效果图,可以用鼠标移动,触摸屏也可以手指滑动,图片会移动,然后移动结束,会有一个回弹的判断. <Window x:Class="_3Dshow.Wi

深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置

求二叉树的宽度和深度 给定一个二叉树,获取该二叉树的宽度和深度. 例如输入 a / \ b c / \ / \ d e f g 返回3. 详细描述: 接口说明 原型: int GetBiNodeInfo(BiNode &head, unsigned int *pulWidth, unsigned int *pulHeight) 输入参数: head 需要获取深度的二叉树头结点 输出参数(指针指向的内存区域保证有效): pulWidth 宽度 pulHeight 高度 返回值: 0 成功 1 失败