iOS開發(fā)-抽屜效果

抽屜效果以前比較多,現(xiàn)在看到的比較少,手Q和今日頭條現(xiàn)在側(cè)邊滑動通過抽屜的方式實現(xiàn),關(guān)于第三方的抽屜效果有很多,稍微對比了一下實用效果比較實用的有兩個RESideMenu和MMDrawerController,網(wǎng)上也有人推薦PPRevealSideViewController單就星星的數(shù)量的數(shù)量而言和上面兩個都不一個層級的,慎重選擇。本文先來看一下兩者的效果,然后介紹抽屜效果實現(xiàn)原理.

RESideMenu

RESlideMenu.gif

代碼實現(xiàn)起來也很簡單:

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[DEMOFirstViewController alloc] init]];
    DEMOLeftMenuViewController *leftMenuViewController = [[DEMOLeftMenuViewController alloc] init];
    DEMORightMenuViewController *rightMenuViewController = [[DEMORightMenuViewController alloc] init];
    
    RESideMenu *sideMenuViewController = [[RESideMenu alloc] initWithContentViewController:navigationController
                                                                    leftMenuViewController:leftMenuViewController
                                                                   rightMenuViewController:rightMenuViewController];
    sideMenuViewController.backgroundImage = [UIImage imageNamed:@"Stars"];
    sideMenuViewController.menuPreferredStatusBarStyle = 1; // UIStatusBarStyleLightContent
    sideMenuViewController.delegate = self;
    sideMenuViewController.contentViewShadowColor = [UIColor blackColor];
    sideMenuViewController.contentViewShadowOffset = CGSizeMake(0, 0);
    sideMenuViewController.contentViewShadowOpacity = 0.6;
    sideMenuViewController.contentViewShadowRadius = 12;
    sideMenuViewController.contentViewShadowEnabled = YES;
    self.window.rootViewController = sideMenuViewController;

抽屜的動畫效果,通過內(nèi)容控制器和抽屜控制器,統(tǒng)一的由RESlideMenu進行管理,RESlideMenu同樣是繼承自UIViewController,支持iOS6.0及其以上手機版本.

MMDrawerController

MMControllers.gif

單從Demo的效果看,作者還是挺用心的,很贊,基本上你需要的效果都能實現(xiàn),用來做今日頭條的抽屜效果毫無壓力。主體實現(xiàn)代碼:

    UIViewController * leftSideDrawerViewController = [[MMExampleLeftSideDrawerViewController alloc] init];

    UIViewController * centerViewController = [[MMExampleCenterTableViewController alloc] init];
    
    UIViewController * rightSideDrawerViewController = [[MMExampleRightSideDrawerViewController alloc] init];
    
    UINavigationController * navigationController = [[MMNavigationController alloc] initWithRootViewController:centerViewController];
    [navigationController setRestorationIdentifier:@"MMExampleCenterNavigationControllerRestorationKey"];
    UINavigationController * rightSideNavController = [[MMNavigationController alloc] initWithRootViewController:rightSideDrawerViewController];
    [rightSideNavController setRestorationIdentifier:@"MMExampleRightNavigationControllerRestorationKey"];
    UINavigationController * leftSideNavController = [[MMNavigationController alloc] initWithRootViewController:leftSideDrawerViewController];
    [leftSideNavController setRestorationIdentifier:@"MMExampleLeftNavigationControllerRestorationKey"];
    self.drawerController = [[MMDrawerController alloc]
                        initWithCenterViewController:navigationController
                        leftDrawerViewController:leftSideNavController
                        rightDrawerViewController:rightSideNavController];
    [self.drawerController setShowsShadow:NO];
    [self.drawerController setRestorationIdentifier:@"MMDrawer"];
    [self.drawerController setMaximumRightDrawerWidth:200.0];
    [self.drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll];
    [self.drawerController setCloseDrawerGestureModeMask:MMCloseDrawerGestureModeAll];
    //http://www.itdecent.cn/users/24da48b2ddb3/latest_articles
    [self.drawerController
     setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
         MMDrawerControllerDrawerVisualStateBlock block;
         block = [[MMExampleDrawerVisualStateManager sharedManager]
                  drawerVisualStateBlockForDrawerSide:drawerSide];
         if(block){
             block(drawerController, drawerSide, percentVisible);
         }
     }];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIColor * tintColor = [UIColor colorWithRed:29.0/255.0
                                          green:173.0/255.0
                                           blue:234.0/255.0
                                          alpha:1.0];
    [self.window setTintColor:tintColor];
    [self.window setRootViewController:self.drawerController];

    return YES;

從最上面的三行代碼我們可以看到抽屜效果實現(xiàn)的邏輯是內(nèi)容和側(cè)邊欄的一個集中控制器,關(guān)于詳細的API可以在文中的底部的參考地址詳細研究~

模擬實現(xiàn)

如果實際開發(fā)中無論是從時間還是從效果上看建議選擇以上兩者中的一種實現(xiàn),以下只是作為抽屜效果的一點探索,與大家分享,只適用于學(xué)習(xí):

抽屜模擬.gif

效果很簡單,實現(xiàn)起來很簡單,這里UITableView展示內(nèi)容,背景視圖當做左右抽屜,偷了懶,UITableView拖動通過UIPanGestureRecognizer實現(xiàn)的,有人是通過UIResponder中的touchesMoved和touchesEnded實現(xiàn)計算偏移量的代碼:

    UITouch *touch = [touches anyObject];
    CGPoint currentPoint = [touch locationInView:self.tableView];
    CGPoint prePoint = [touch previousLocationInView:self.tableView];

對于UITableView是無效的,內(nèi)容如果是單純的UIView是可以通過以上代碼實現(xiàn)抽屜效果的;
數(shù)據(jù)初始化代碼:

    for (NSInteger i=0;i<5; i++) {
        [self.dataSource addObject:[NSString stringWithFormat:@"FlyElephant-%ld",i]];
    }
    
    [self.view addSubview:self.leftDrawer];
    UIPanGestureRecognizer *panGesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureRecognizer:)];
    [self.tableView addGestureRecognizer:panGesture];
    [self.view addSubview:self.tableView];

宏定義:

#define SCREENWIDTH [[UIScreen mainScreen] bounds].size.width
#define SCREENHEIGHT [[UIScreen mainScreen] bounds].size.height
#define MAXYOFFSET   200
#define ENDRIGHTX    200
#define ENDLEFTX    -200</code></pre>
手勢控制`panGestureRecognizer:(UIPanGestureRecognizer *)panGesture`代碼:
CGPoint transition = [panGesture translationInView:self.tableView];
self.tableView.frame=[self panGestureOffset:transition.x];
[panGesture setTranslation:CGPointZero inView:self.tableView];
//拖動手勢結(jié)束
if (panGesture.state==UIGestureRecognizerStateEnded) {
    CGFloat originX =self.tableView.frame.origin.x;
    CGFloat offsetX=0;
    //大于屏幕的一半進入新的位置
    if (originX > SCREENWIDTH*0.5) {
        offsetX=ENDRIGHTX-originX;
    }else if(originX < SCREENWIDTH*0.5 && originX > -SCREENWIDTH*0.5){
        //小于屏幕的一半,大于屏幕負一半的時候,則恢復(fù)到初始狀態(tài)
        offsetX=offsetX-originX;
    }else if (originX<-SCREENWIDTH*0.5){
        offsetX=ENDLEFTX-originX;
    }
    
    [UIView animateWithDuration:0.5 animations:^{
        self.tableView.frame=[self panGestureOffset:offsetX];
    }];
}
偏移量`panGestureOffset:(CGFloat)offsetX`控制:  
offsetX=self.tableView.frame.origin.x+offsetX;
CGFloat offsetY = offsetX/SCREENWIDTH * MAXYOFFSET;
//如果需要設(shè)置右邊的抽屜,參數(shù)為負數(shù),需要取絕對值
CGFloat scale = (SCREENHEIGHT-fabs(2*offsetY))/SCREENHEIGHT;
CGFloat height = SCREENHEIGHT*scale;
CGFloat width  = SCREENWIDTH;
CGFloat x = offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5;

return CGRectMake(x, y, width, height);
### 參考鏈接
[RESideMenu](https://github.com/romaonthego/RESideMenu)
[MMDrawerController](https://github.com/mutualmobile/MMDrawerController)
[FEDrawerMenu](https://github.com/SmallElephant/FEDrawerMenu/tree/master)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,102評論 4 61
  • 這是第二次感受寫作收獲,與第一次最大的不同是:開始喜歡接受生活中每天有寫作的習(xí)慣了。 總結(jié)寫作給自己生活帶來的變化...
    唐薇閱讀 323評論 2 2
  • bootstrap是最受歡迎的HTML、CSS、JS的框架,用于開發(fā)響應(yīng)式布局,移動設(shè)備優(yōu)先的項目是為所有開發(fā)者、...
    Man僵小魚閱讀 352評論 0 1

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