• 更好的抽屉效果(ios)


    昨天项目基本没啥事了,晚上早早的就回家了,躺在床上无聊地玩着手机(Android的),在清理系统垃圾时被一个“360手机助手”给吸引了,

    其实我是被它的那个抽屉效果给吸引了,此时你也许会觉得我out了 ,一个抽屉效果有啥好吸引人的。

    以前在项目中我也用到过抽屉,也看过大量的抽屉效果,大部分时间时只有一个view可以滑动的,下面那个view是不动的,就像是拉出或推出一个view的效果差不多,

    但看到这个 360手机助手的抽屉效果时,我觉得原来的那些真没这个好看。在这个程序中,当你左右拖动那个view A时,另外一个view B也会相应的滑动,但滑动的幅度没有你拖动的那个view A大,不知道我表达清楚没有,你可以下载个360手机助手看看。

    于是今天就模仿了一下,拖动view A时 两个view都可以滑动,则说明动画时作用两个view的。

    下面直接上代码吧,代码很简单,也没具体完善逻辑,只是个简单的效果实现 ,了解抽屉效果的很容易就看懂的

    1.工程结构图

    2.主要的代码

    //
    //  Drawer.h
    //  SlideDrawer
    //
    //  Created by PSH_Chen_Tao on 10/12/13.
    //  Copyright (c) 2013 wolfman. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    //表明当前状态的枚举常量
    typedef enum{
        DrawerStatusLeft,
        DrawerStatusRight
    }DrawerStatus;
    
    @interface Drawer : UIView
    
    //初始化方法
    -(id)initWithParent:(UIViewController *)parentViewController firstContent:(UIViewController *)firstContentViewController  secondContent:(UIViewController *)secondContentViewController;
    
    @end
    View Code
      1 //
      2 //  Drawer.m
      3 //  SlideDrawer
      4 //
      5 //  Created by PSH_Chen_Tao on 10/12/13.
      6 //  Copyright (c) 2013 wolfman. All rights reserved.
      7 //
      8 
      9 #import "Drawer.h"
     10 #define kDistance 50
     11 //#define firstContentMoveDistance 100
     12 @implementation Drawer{
     13     UIViewController *parent;
     14     
     15     //控制第一个内容view的controller
     16     UIViewController *firstContent;
     17     //控制第二个内容view的controller
     18     UIViewController *secondContent;
     19     
     20     
     21     // 左滑时 firstContent的 view的center
     22     CGPoint firstLeft;
     23     // 右滑时 firstContent的 view的center
     24     CGPoint firstRight;
     25     
     26     // 左滑时 secondContent的 view的center
     27     CGPoint secondLeft;
     28     // 右滑时 secondContent的 view的center
     29     CGPoint secondRight;
     30     
     31     // 目前的状态
     32     DrawerStatus status;
     33     
     34     // firstContent  的 center
     35     CGPoint firstContentCenter;
     36     
     37     
     38     //移动比列,这个是关键,本程序是类似360手机助手一样的效果,两边的view都是
     39     //可同时移动的,在此就需要一个很好的匹配,移动时两个view的间距不能增大或减小
     40     float moveScale;
     41 }
     42 
     43 
     44 -(id)initWithParent:(UIViewController *)parentViewController firstContent:(UIViewController *)firstContentViewController  secondContent:(UIViewController *)secondContentViewController{
     45     parent = parentViewController;
     46     firstContent = firstContentViewController;
     47     secondContent = secondContentViewController;
     48     // 为了便于效果查看
     49     firstContent.view.backgroundColor = [UIColor redColor];
     50     secondContent.view.backgroundColor = [UIColor greenColor];
     51     
     52     //设置frame
     53     self = [super initWithFrame:CGRectMake(0, 0, parent.view.frame.size.width, parent.view.frame.size.height)];
     54     if (self) {
     55         firstContent.view.frame = CGRectMake(0, 0, self.frame.size.width, parent.view.frame.size.height);
     56         [self addSubview:firstContent.view];
     57         secondContent.view.frame = CGRectMake(0, 0, parent.view.frame.size.width, parent.view.frame.size.height);
     58         [self addSubview:secondContent.view];
     59         
     60         // 下面算firstContent 和 secondContent的左右中心点时是要遵循一定关系的,
     61         //firstContent  和 secondContent 的可移动距离之和必须等于 parent的宽度
     62         firstLeft = CGPointMake(self.frame.size.width/2 - kDistance, self.frame.size.height/2);
     63         firstRight = self.center;
     64         
     65         secondLeft = self.center;
     66         secondRight = CGPointMake(self.frame.size.width+secondContent.view.frame.size.width/2-kDistance, self.frame.size.height/2);
     67         
     68         firstContent.view.center = firstRight;
     69         secondContent.view.center = secondRight;
     70         status = DrawerStatusRight;
     71         
     72         // 加入手势
     73         UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
     74         tap.numberOfTapsRequired = 1;
     75         tap.enabled = YES;
     76         [secondContent.view addGestureRecognizer:tap];
     77         
     78         UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
     79         pan.enabled = YES;
     80         [secondContent.view addGestureRecognizer:pan];
     81         
     82         //设置第一个view 的起始center
     83         firstContentCenter = firstContent.view.center;
     84         
     85         //这个是关键,为什么要这样算,为了防止两个content view之间的间距发生改变,
     86         //所以firstContent  和 secondContent 的可移动距离之和必须等于 parent的宽度
     87         moveScale = (float)kDistance/(float)(self.frame.size.width - kDistance);
     88     }
     89     
     90     return  self;
     91 }
     92 
     93 
     94 -(void)handleTap:(UITapGestureRecognizer *)tap{
     95     // 当secondController完全出现在屏幕中时,则只有点击左上角时才有用
     96     // 呵呵,没啥好写的,就是简单地控制下点击范围
     97     if (status == DrawerStatusLeft) {
     98         
     99         CGPoint p = [tap locationInView:secondContent.view];
    100         if (p.x > kDistance || p.y > 50) {
    101             return;
    102         }
    103     }
    104     
    105     [UIView animateWithDuration:0.3 delay:0.01 options:UIViewAnimationOptionCurveLinear animations:^{
    106         if (status == DrawerStatusRight) {
    107             secondContent.view.center = secondLeft;
    108 
    109             firstContent.view.center = firstLeft;
    110             status = DrawerStatusLeft;
    111         }else{
    112             secondContent.view.center = secondRight;
    113             firstContent.view.center = firstRight;
    114             status = DrawerStatusRight;
    115         }
    116     } completion:nil];
    117     
    118 }
    119 
    120 
    121 -(void)handlePan:(UIPanGestureRecognizer *)pan{
    122     
    123     CGPoint point = [pan translationInView:self];
    124     
    125     if (secondContent.view.center.x + point.x < secondLeft.x) {
    126         
    127         secondContent.view.center = secondLeft;
    128         firstContent.view.center = firstLeft;
    129         
    130     }else if (secondContent.view.center.x + point.x > secondRight.x){
    131         
    132         secondContent.view.center = secondRight;
    133 
    134         firstContent.view.center = firstRight;
    135         
    136     }else{
    137         secondContent.view.center = CGPointMake(secondContent.view.center.x + point.x, secondContent.view.center.y);
    138         //firstContent的移动距离必须按照比例计算
    139         firstContent.view.center  =  CGPointMake(firstContent.view.center.x + point.x*moveScale, firstContent.view.center.y);
    140     }
    141     
    142     [pan setTranslation:CGPointMake(0, 0) inView:self];
    143     if (pan.state == UIGestureRecognizerStateEnded) {
    144         [UIView animateWithDuration:0.3 delay:0.01 options:UIViewAnimationOptionCurveLinear animations:^{
    145             if (secondContent.view.center.x < secondRight.x*4/5) {
    146                 
    147                 secondContent.view.center = secondLeft;
    148 
    149                 firstContent.view.center = firstLeft;
    150                 status = DrawerStatusLeft;
    151             }else{
    152                 
    153                 secondContent.view.center = secondRight;
    154                 firstContent.view.center = firstRight;
    155 
    156                 status = DrawerStatusRight;
    157             }
    158         } completion:nil];
    159     }
    160 }
    161 
    162 @end
    View Code

    上面两段是主要的代码了,下面是使用的地方

     1 //
     2 //  ViewController.m
     3 //  SlideDrawer
     4 //
     5 //  Created by PSH_Chen_Tao on 10/12/13.
     6 //  Copyright (c) 2013 wolfman. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 #import "FirstViewController.h"
    12 #import "SecondViewController.h"
    13 #import "Drawer.h"
    14 @interface ViewController ()
    15 
    16 @end
    17 
    18 @implementation ViewController
    19 
    20 - (void)viewDidLoad
    21 {
    22     [super viewDidLoad];
    23     // Do any additional setup after loading the view, typically from a nib.
    24     
    25     FirstViewController *fisrt = [[FirstViewController alloc]initWithNibName:@"FirstViewController" bundle:nil];
    26     
    27     SecondViewController *second = [[SecondViewController alloc]initWithNibName:@"SecondViewController" bundle:nil];
    28     
    29     Drawer *drawer = [[Drawer alloc]initWithParent:self firstContent:fisrt secondContent:second];
    30     [self.view addSubview:drawer];
    31 }
    32 
    33 - (void)didReceiveMemoryWarning
    34 {
    35     [super didReceiveMemoryWarning];
    36     // Dispose of any resources that can be recreated.
    37 }
    38 
    39 @end
    View Code

    呵呵,可以看看效果,是不是感觉好点。。

  • 相关阅读:
    Android作业10/21
    Android作业10/07
    Android作业0930
    Android作业 0923
    第四周作业
    第七周
    第六周
    第四周作业
    3.10第二次
    jsp第一次作业
  • 原文地址:https://www.cnblogs.com/ctaodream/p/3365352.html
Copyright © 2020-2023  润新知