zoukankan      html  css  js  c++  java
  • iOS_20_微博Dock的尾随切换

    终于效果图:Dock尾随HomeVC一起切换




    要求:

    当点击HomeVC里面的微博列表的某一行时候,

    push到StatusDetail微博详情控制器,而且Dock也一起消失

    当点击StatusDetail微博详情控制器上面的左边返回button,Dock也跟着HomeVC一起回来


    HomeVC.m

    // 点击列表中的一条微博,创建一个StatusDetailViewController,并为其成员status赋值(数据来源),并通过导航push入栈
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // 创建一个微博正文详情控制器,
        StatusDetailViewController *detailVC = [[StatusDetailViewController alloc] init];
        // 为即将跳转的微博正文控制器,传递weibo数据(以供其显示用)
        StatusListCellFrame *statusListCellFrame = _statusCellFrames[indexPath.row];
        detailVC.status = statusListCellFrame.status;
        // 通过导航控制器跳转过去
        [self.navigationController pushViewController:detailVC animated:YES];
    }




    如上图所看到的,

    主控制器(BeyondVC)的view包括两个部分:

    1,上部的导航控制器  2,以下的Dock




    上部的导航控制器的view又包含两个部分:

    1,上部的导航条(push的时候,始终不动)

    2,下部的根控制器(HomeVC)(push的时候会动画切换)







    为了让Dock和导航控制器的根控制(HomeVC)能一起滑过去,又可以一起滑回来,

    必须让主控制器(BeyondVC)成为导航控制器的代理,

    使之可以监听push动作之willShowViewController和didShowViewController方法




    在以下的willShowViewController方法中,

    先将Dock从主控制器(BeyondVC)上移除,然后加入到导航控制器的根控制(HomeVC)里面



    导航控制器的代理方法     willShowViewController


    #pragma mark - 导航控制器的代理方法
    // 屏幕宽 320
    #define kWinWidth self.view.bounds.width
    // 屏幕高 480
    #define kWinHeight self.view.bounds.height
    // 顶部状态条 20
    #define kStatusBarHeight 20
    
    // 目的是,监听push动作,在新控制器将进入栈顶时,设置左边button为返回箭头,设置右边button为回到首页
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        //重要~~~~
        // 先取得根控制器
        UIViewController *rootVC = navigationController.viewControllers[0];
        
        // 假设将要显示的控制器(将被push入栈的), 不是栈底控制器(根控制器)。才须要设置左边为返回button,右边为首页button
        if (viewController != rootVC) {
            
            // 左边的返回到上一个控制器
            viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithBgIcon:@"navigationbar_back.png" target:self action:@selector(popToPreviousVC)];
            
            // 右边的回到首页button,即回到栈底控制器(即从详情页回到列表页)
            viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithBgIcon:@"navigationbar_home.png" target:self action:@selector(backToRootVC)];
            
            
            // 1,先拉长导航控制器的view的高度 为整个窗体的高度-20 (由于dock消失后,底部会多空出黑色的空间)
            navigationController.view.frame = CGRectMake(0, 20,320,480 - 20);
            
            // 2,先让Dock从主控制器(BeyondViewController)的view上移除
            [_dock removeFromSuperview];
            
            
            // 3,为了在Push下一个控制器,让dock和根控制器一起平移,所以,加入dock到导航控制器的根控制器的view上 ,并又一次调整Dock在HomeVC的view中的Y值就可以,注意导航不会移动,移的是导航的根控制器,而根控制器的原点(0 0)是 :20+导航栏高度44
            
            // 假设根控制器是能够滚动的,则要注意y的原点是在tableView的顶部(当向下滚了一定的距离之后)
            if ([rootVC.view isKindOfClass:[UIScrollView class]]) {
                UIScrollView * scrollV =  (UIScrollView *)rootVC.view;
                // dock的导航控制器的根控制器里面的y值
                // 由于滚动之后,rootView的左上角到顶上非常远的地方了
                _dock.frame =CGRectMake(0, scrollV.contentOffset.y + 460 - kDockHeight, 320, kDockHeight );
            } else {
                // dock的导航控制器的根控制器里面的y值
                _dock.frame =CGRectMake(0, 480 - 20 - 2*kDockHeight, 320, kDockHeight );
    
            }
            // 4,最后再加入dock到导航控制器的根控制器里面(rootVC界面上(即导航控制器的根控制器),目的是push新的VC的时候,让dock和导航控制器的根控制器一起平移到界面的左边去,当点击返回键的时候,dock又能和rootVC一起回来
            [rootVC.view addSubview:_dock];
            
        }
    }
    
    




    在以下的didShowViewController方法中,

    先将Dock从导航控制器的根控制(HomeVC)上移除,然后加入到主控制器(BeyondVC)里面




    导航控制器的代理方法    didShowViewController

    // 导航控制器的Y = 20,导航控制器的高度 =  总高度 - DOCK高度 - 20
    #define kContentFrame CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height - kDockHeight - 20)
    
    // BeyondVC主控制器中,DOCK的Y = 总高度 - DOCK高度
    #define KDockFrame CGRectMake(0, self.view.frame.size.height - kDockHeight, self.view.frame.size.width, kDockHeight)
    
    // 目的是,监听push动作,在新控制器已经显示的时候,将dock从导航控制器中移除,再又又一次显示到主控制器
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        // 先取得导航 的栈底的根控制器
        UIViewController *rootVC = navigationController.viewControllers[0];
        // 假设要显示的控制器是根控制器,又一次把Dock
        if (viewController == rootVC) {
            // 更改导航控制器view的frame
            // 导航控制器的Y = 20,导航控制器的高度 =  总高度 - DOCK高度 - 20
            navigationController.view.frame = kContentFrame;
            
            // 将Dock先从栈底的根控制器rootVC上移除
            [_dock removeFromSuperview];
            
            // 再加入dock到BeyondViewController,DOCK的Y = 总高度 - DOCK高度
            _dock.frame = KDockFrame;
            [self.view addSubview:_dock];
        }
    }
    
    




    这样就实现了,让主控制器里面的Dock尾随导航控制器的根控制器,一起消失,又一起回来~


  • 相关阅读:
    正则表达式
    http协议组成(请求状态码)
    谈一谈你对js线程的理解
    CSS 中定位方式有几种,说明他们的意义
    手机端白屏前端优化的方法,5 种以上
    用 js 写一个获取随机颜色的程序
    如何获取本地存储信息
    cuda 版本查阅
    ubuntu16.04 ROS安转及RVIZ启动
    Tensorflow和Caffe 简介
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6747354.html
Copyright © 2011-2022 走看看