zoukankan      html  css  js  c++  java
  • iOS开发——UI进阶篇(十)导航控制器、微博详情页、控制器的View的生命周期

    一、导航控制器出栈


    1、initWithRootViewController本质

        UIViewController *vc = [[OneViewController alloc] init];
        // 创建导航控制器
        // 导航控制器必须要有一个根控制器
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
        // 会调用push方法
        // initWithRootViewController底层其实是调用导航控制器的push方法,把vc成为导航控制器的子控制器
        // 一旦把一个控制器压入到栈,就会把这个控制器的view添加到导航控制器的view上
        //    [nav pushViewController:vc animated:YES];

    2、回到上个控制器或者根控制器

    // 回到上一个控制器
    - (IBAction)back2Pre:(id)sender {
        
        // 导航控制器中做界面之间的跳转必须拿到导航控制器
        [self.navigationController popViewControllerAnimated:YES];
        
        // 调用pop方法并不会马上销毁当前控制器
        
    }
    // 回到根控制器
    - (IBAction)back2Root:(id)sender {
        
    //    [self.navigationController popToRootViewControllerAnimated:YES];
        
        // 还有一种方法:指定回到哪个控制器
        // popToViewController使用注意点,传入进去的控制器必须是导航控制器栈里面的控制器
        [self.navigationController popToViewController:self.navigationController.childViewControllers[0] animated:YES];
    }

    二、设置导航条内容


    1、UINavigationItem:是一个模型,决定导航条的内容(左边内容,中间,右边内容)
    2、UIBarButtonItem:是一个模型,决定导航条上按钮的内容
    只要看到item,通常都是苹果提供的模型,只要改模型就能修改苹果的某些控件.

             // 1、设置导航条的标题
        self.navigationItem.title = @"chg";
        self.navigationItem.titleView = [UIButton buttonWithType:UIButtonTypeContactAdd];
        
            // 2、设置导航条左边的内容
        UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithTitle:@"abc" style:UIBarButtonItemStyleDone target:self action:@selector(leftClick)];
        self.navigationItem.leftBarButtonItem = leftItem;
        
            // 3、设置导航条右边的内容
        
        // 在iOS7之后,默认会把导航条上的按钮的图片渲染成蓝色.
        // 不想要渲染导航条上的按钮的图片颜色
        UIImage *image = [UIImage imageNamed:@"navigationbar_friendsearch"];
        // 告诉苹果哪个图片不要渲染
        image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        // UIBarButtonItem
        UIBarButtonItem *rigthItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStyleDone target:nil action:nil];
        
        // 创建按钮
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        // 正常
        [btn setBackgroundImage:[UIImage imageNamed:@"navigationbar_friendsearch"] forState:UIControlStateNormal];
        // 高亮
        [btn setBackgroundImage:[UIImage imageNamed:@"navigationbar_friendsearch_highlighted"] forState:UIControlStateHighlighted];
        
        // 导航条上的子控件位置不需要我们管理,只需要管理尺寸
        btn.frame = CGRectMake(0, 2000, 30, 30);
        
        UIBarButtonItem *rigthItem1 = [[UIBarButtonItem alloc] initWithCustomView:btn];
        
        // self.navigationItem.rightBarButtonItem = rigthItem; 
        // 可添加多个
        self.navigationItem.rightBarButtonItems = @[rigthItem,rigthItem1];

    三、控制器的View的生命周期


    // 监听控制器的view的生命周期方法
    // 控制器的view的生命周期方法都是以view开头
    
    // 控制器的view即将显示的时候调用
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
         NSLog(@"%s",__func__);
    }
    
    // 控制器的view完全显示的时候调用
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
         NSLog(@"%s",__func__);
    }
    // 控制器的view即将消失的时候调
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
         NSLog(@"%s",__func__);
    }
    
    // 控制器的view完全消失的时候调
    - (void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
         NSLog(@"%s",__func__);
    }
    
    // 控制器的view即将布局子控件的时候调用
    - (void)viewWillLayoutSubviews
    {
        [super viewWillLayoutSubviews];
         NSLog(@"%s",__func__);
    }
    // 控制器的view布局子控件完成的时候调用
    - (void)viewDidLayoutSubviews
    {
        [super viewDidLayoutSubviews];
         NSLog(@"%s",__func__);
    }
    
    // 当控制器的view加载完成的时候调用
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"%s",__func__);
    }

    执行顺序: viewDidLoad ->  viewWillAppear ->  viewWillLayoutSubviews -> viewDidLayoutSubviews ->  viewDidAppear -> viewWillDisappear -> viewDidDisappear

    在非ARC中经常使用

    // Unload:卸载这个view
    - (void)viewWillUnload
    {
        [super viewWillUnload];
    }
    
    // 表示控制器的view卸载完成
    - (void)viewDidUnload
    {
        [super viewDidUnload];
        
        // 清空界面上的数据
        self.datas = nil;
        
    }
    清空界面原理:
    - (void)setDatas:(NSMutableArray *)datas
    {
        if (_datas != datas) {
            _datas = [datas retain];
            [datas release];
        }
    }

    四、微博个人详情页


    大致的功能如上,导航条和文字的透明度随着移动而变化,粉红色视图有悬浮效果,并且鲨鱼图片随着滚动等比缩放,始终与粉红色视图紧挨在一起

    1、搭建框架

    首先拖一个Navigation Controller

    设置这个控制器的根控制器为右边的View Controller

    那么现在主要精力放在View Controller上

    首先最底部是View Controller的view

    view上面有Table View、粉红色的视图、最上面的头部视图

    头部视图上面有鲨鱼图片和鸣人图片

    注意:Table View必须铺满整个View Controller的view 【在代码中设置上面的额外滚动高度为(粉红色的视图的高度+最上面的头部视图的高度)】

    具体结构图如下:

    2、实现代码如下:

      1 #import "ViewController.h"
      2 // 1.项目结构:导航控制器,导航控制器上添加一个个人详情控制器
      3 // 2.分析个人详情页的结构
      4 // 2.1 tableView(尺寸跟控制器尺寸一样大)
      5 // 2.2 头部视图不能是tableView的头部视图 + 粉红色的选项卡视图不能是tabelView的头部视图
      6 // 2.3 tableView的头部视图没有悬停效果,tableView分组的头部视图才有悬停效果
      7 
      8 #import "UIImage+Image.h"
      9 
     10 @interface ViewController ()<UITableViewDelegate>
     11 @property (weak, nonatomic) IBOutlet UITableView *tableView;
     12 
     13 // 记录一开始lastOffsetY
     14 @property (nonatomic, assign) CGFloat lastOffsetY;
     15 
     16 //@property (weak, nonatomic) IBOutlet NSLayoutConstraint *headYCons;
     17 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *headHCons;
     18 
     19 
     20 @property (nonatomic, weak) UILabel *label;
     21 
     22 @end
     23 
     24 #define XMGHeadH 200
     25 #define XMGHeadMinH 64
     26 #define XMGTabBarH 44
     27 
     28 @implementation ViewController
     29 
     30 - (void)viewDidLoad {
     31     [super viewDidLoad];
     32     // Do any additional setup after loading the view, typically from a nib.
     33     
     34     // 在iOS7之后,导航控制器下的所有UIScrollView默认顶部都会添加64的额外滚动区域.
     35     // 不需要添加额外的滚动区域
     36     self.automaticallyAdjustsScrollViewInsets = NO;
     37     
     38     // 一开始y轴滚动区域是-244.
     39     _lastOffsetY = - (XMGHeadH + XMGTabBarH);
     40     
     41     // 设置tableView顶部的额外的滚动区域(选项卡的高度 + 头部视图的高度)
     42     self.tableView.contentInset = UIEdgeInsetsMake(XMGHeadH + XMGTabBarH, 0, 0, 0);
     43  
     44     // 清空导航条的背景
     45     // 如何快速的清空导航条背景图片,直接传入一个空图片的UIImage对象
     46     [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
     47     // 清空阴影图片
     48     [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
     49     
     50     // 设置导航条标题
     51     UILabel *label = [[UILabel alloc] init];
     52     
     53     _label = label;
     54     
     55     label.textColor = [UIColor colorWithWhite:1 alpha:0];
     56     
     57     label.text = @"chg的个人主页";
     58     
     59     // 自动计算当前label文字尺寸,并且设置控件的尺寸和文字尺寸一样.
     60     [label sizeToFit];
     61 
     62     self.navigationItem.titleView = label;
     63     
     64 }
     65 // 返回tableView有多少行
     66 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
     67 {
     68     return 20;
     69 }
     70 
     71 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     72 {
     73     static NSString *ID = @"cell";
     74     
     75     // 从缓存池中获取cell
     76     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
     77     
     78     if (cell == nil) {
     79         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
     80         cell.backgroundColor = [UIColor redColor];
     81     }
     82     
     83     cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
     84     
     85     return cell;
     86 }
     87 
     88 #pragma mark - 监听tableView滚动
     89 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
     90 {
     91     // 获取当前滚动的偏移量值contentOffset
     92     CGFloat offsetY = scrollView.contentOffset.y;
     93     
     94     
     95     // contentOffset:tableView可视范围顶点与内容开始点的偏移量,内容开始点的contentOffset = 0;
     96     
     97     // 计算下用户相对最开始偏移量滚动的多少
     98     CGFloat delta = offsetY - _lastOffsetY;
     99     
    100     // 移动头部视图
    101     // 当往上移动的时候,头部视图需要往上移动,高度值需要减少
    102     CGFloat headH = XMGHeadH - delta;
    103     
    104     // 如果小于最小高度,就不在减少了
    105     if (headH < XMGHeadMinH) {
    106         headH = XMGHeadMinH;
    107     }
    108     
    109     _headHCons.constant = headH;
    110     
    111     // 处理导航条
    112     // 获取当前透明度,当用户移动136的时候透明度刚好为1,delta就是用户移动的距离.
    113     CGFloat alpha = delta / (XMGHeadH - XMGHeadMinH) * 1;
    114     
    115     if (alpha > 1) {
    116         alpha = 0.99;
    117     }
    118     
    119     // 描述颜色
    120     UIColor *color = [UIColor colorWithWhite:1 alpha:alpha];
    121     
    122     // 设置导航条背景图片的透明度
    123     [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:color] forBarMetrics:UIBarMetricsDefault];
    124     
    125     // 设置文字的透明度
    126     _label.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    127 }
    128 
    129 @end

    这里的headHCons是头部视图的约束高度。

    3.根据颜色生成一张1*1的相同颜色图片

    UIImage+Image.h

    #import <UIKit/UIKit.h>
    
    @interface UIImage (Image)
    
    
    // 根据颜色生成一张尺寸为1*1的相同颜色图片
    + (UIImage *)imageWithColor:(UIColor *)color;
    
    
    @end

    UIImage+Image.m

    #import "UIImage+Image.h"
    
    @implementation UIImage (Image)
    
    + (UIImage *)imageWithColor:(UIColor *)color
    {
        // 描述矩形
        CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
        
        // 开启位图上下文
        UIGraphicsBeginImageContext(rect.size);
        // 获取位图上下文
        CGContextRef context = UIGraphicsGetCurrentContext();
        // 使用color演示填充上下文
        CGContextSetFillColorWithColor(context, [color CGColor]);
        // 渲染上下文
        CGContextFillRect(context, rect);
        // 从上下文中获取图片
        UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
        // 结束上下文
        UIGraphicsEndImageContext();
        
        return theImage;
    }
    
    
    @end

    到这里功能基本也就实现了

    将来的你会感谢今天如此努力的你! 版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Windows通过DOS命令进入MySQL的方法
    php使用phpqrcode生成二维码
    js字符串转换为Json对象的三种写法
    Linux系统中RPM软件包安装语法
    Linux系统中软件安装方式以及特点
    vue-生存周期
    echart力导向图
    css样式,高斯模糊
    某布局
    跨浏览器兼容
  • 原文地址:https://www.cnblogs.com/chglog/p/4690601.html
Copyright © 2011-2022 走看看