• ios开发-UI基础-应用管理(单纯界面)改进3-xib使用


      [注意]转载请注明出处:http://www.cnblogs.com/hukezhu/  

      上篇文章是使用了字典转模型的方法实现的,本篇引入一个新的概念xib(描述局部界面的文件)(相对于storyboard描述全局界面来说).

      使用xib可以使用可视化界面开发来代替完全代码开发.(当然这不是绝对的,一般实际开发中会结合使用).

      xib文件的加载过程:
        0> 根据路径, 搜索对应的xib文件(nib文件)
        1> 加载xib文件的时候, 会按顺序加载xib文件中的每个控件。
        2> 对于每个控件, 创建的时候都会查找对应的Class属性中配置的是那个类, 那么就创建对应的类的对象。
        3> 获取到某个视图以后, 按照在xib中配置的属性的值, 放在数组中,
        4> 最后返回一个数组, 这个数组中包含创建的所有元素对象。

      使用xib封装一个自定义view的步骤
        1> 新建一个AppView.xib文件来描述AppView内部的结构
        2> 新建一个继承UIView的自定义view,假设类名叫做(appView)
        3> 修改UIView的类型为appView真实类型
        4> 将内部的子控件跟appView进行属性连线
        5> appView提供一个模型属性
        6> 重写模型属性的set方法,因为在set方法中可以拿到外界控制器传递的模型数据
        7> 把模型数据拆开,分别设置数据到对应的子控件中
        补充:提供一个创建AppView的类方法,将读取xib文件的代码屏蔽起来

      xib文件的创建过程:

      xcode界面下,commond+ N--->ios--->Users interface--->view---->create如下图:   

    附上源代码:

    KZAppView.h

     1 //
     2 //  KZAppModel.h
     3 //  UI基础-03-05-14
     4 //
     5 //  Created by hukezhu on 15/5/15.
     6 //
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/
    11 @interface KZAppModel : NSObject
    12 /**
    13  *  应用图标
    14  */
    15 @property (nonatomic ,copy) NSString *icon;
    16 /**
    17  *  应用名称
    18  */
    19 @property (nonatomic ,copy) NSString *name;
    20 
    21 /**
    22  *  通过字典来初始化对象
    23  *
    24  *  @param dict 字典对象
    25  *
    26  *  @return 已经初始化完毕的模型对象
    27  */
    28 - (instancetype)initWithDict:(NSDictionary *)dict;
    29 
    30 //类方法
    31 + (instancetype)appWithModelDict:(NSDictionary *)dict;
    32 
    33 @end

    KZAppView.m

     1 //
     2 //  KZAppModel.m
     3 //  UI基础-03-05-14
     4 //
     5 //  Created by hukezhu on 15/5/15.
     6 //
     7 //
     8 
     9 #import "KZAppModel.h"
    10 
    11 @implementation KZAppModel
    12 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/
    13 //对象方法
    14 -(instancetype)initWithDict:(NSDictionary *)dict{
    15 
    16     //重写构造方法的默认写法
    17     if(self = [super init]){
    18     
    19         //将字典的所有属性赋值给模型
    20         self.icon = dict[@"icon"];
    21         self.name = dict[@"name"];
    22     }
    23     return self;
    24 }
    25 //类方法
    26 +(instancetype)appWithModelDict:(NSDictionary *)dict{
    27 
    28     //注意此处是self
    29     return [[self alloc]initWithDict:dict];
    30 }
    31 @end

    ViewController.m

      1 //
      2 //  ViewController.m
      3 //  03-应用管理
      4 //
      5 //  Created by hukezhu on 15/5/14.
      6 //
      7 //
      8 
      9 #import "ViewController.h"
     10 #import "KZAppModel.h"
     11 
     12 @interface ViewController ()
     13 @property (nonatomic,strong)NSArray *apps;
     14 @end
     15 
     16 @implementation ViewController
     17 
     18 - (void)viewDidLoad {
     19     [super viewDidLoad];
     20     
     21     //每一行的应用的个数
     22     int totalCol = 3;
     23     /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/
     24     
     25     //添加一个小的view
     26     CGFloat appW = 80;
     27     CGFloat appH = 100;
     28     CGFloat marginX = 20;
     29     CGFloat marginY = 20;
     30     CGFloat hightMargin = 30;
     31     CGFloat leftMargin = (self.view.frame.size.width - totalCol * appW - (totalCol - 1) *marginX)* 0.5;
     32     
     33     
     34     
     35     for (int i = 0; i < self.apps.count; i++) {
     36         
     37         
     38         //计算行号和列号
     39         int row = i / totalCol;
     40         int col = i % totalCol;
     41         
     42         CGFloat appX = leftMargin + (marginX + appW)* col;
     43         CGFloat appY = hightMargin + (marginY + appH)* row;
     44         
     45         //1.添加view
     46     
     47        
     48         //首先拿到一个格子视图
     49         UIView *appView = [[NSBundle mainBundle]loadNibNamed:@"KZAppView" owner:nil options:nil][0];
     50         
     51         //1.2设置frame
     52         appView.frame = CGRectMake(appX, appY, appW, appH);
     53         //1.3设置背景色(便于代码阶段验证,之后会删除)
     54         //appView.backgroundColor = [UIColor redColor];
     55         //1.4将这个appView添加到view中
     56         [self.view addSubview:appView];
     57         
     58         //加载数据
     59         //NSDictionary *dict = self.apps[i];
     60         //将数据赋值给模型对象
     61         KZAppModel *appModel = self.apps[i];
     62         
     63         
     64         //通过数组的特性拿到里面的小控件,进行赋值
     65         UIImageView *imageView = (UIImageView *)appView.subviews[0];
     66         imageView.image = [UIImage imageNamed:appModel.icon];
     67         
     68         UILabel *label = appView.subviews[1];
     69         label.text = appModel.name;
     70         
     71         UIButton *downBtn = (UIButton *)appView.subviews[2];
     72         [downBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];
     73         
     74         
     75 //        //2.添加图片UIImageView
     76 //        CGFloat imageW = 60;
     77 //        CGFloat imageH = 50;
     78 //        CGFloat imageX = (appW - imageW)*0.5;
     79 //        CGFloat imageY = 0;
     80 //        UIImageView *imageView = [[UIImageView alloc]init];
     81 //        imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);
     82 //        //imageView.backgroundColor = [UIColor blueColor];
     83 //        //imageView.image = [UIImage imageNamed:dict[@"icon"]];
     84 //        //从模型对象中取出数据
     85 //        imageView.image = [UIImage imageNamed:appModel.icon];
     86 //        [appView addSubview:imageView];
     87 //    
     88 //        
     89 //        //3.添加应用名称
     90 //    
     91 //        CGFloat labelW = 80;
     92 //        CGFloat labelH = 25;
     93 //        CGFloat labelX = 0;
     94 //        CGFloat labelY = imageH;
     95 //        UILabel *label = [[UILabel alloc]init];
     96 //        label.frame = CGRectMake(labelX, labelY, labelW, labelH);
     97 //        //label.backgroundColor = [UIColor grayColor];
     98 //        //label.text = dict[@"name"];
     99 //        //从模型对象中取出数据name
    100 //        label.text = appModel.name;
    101 //        
    102 //        //设置字体大小
    103 //        label.font = [UIFont systemFontOfSize:13];
    104 //        //设置字体居中
    105 //        label.textAlignment = NSTextAlignmentCenter;
    106 //        [appView addSubview:label];
    107 //        
    108 //        //4.添加下载按钮
    109 //        
    110 //        CGFloat downloadW = 60;
    111 //        CGFloat downloadH = 25;
    112 //        CGFloat downloadX = 10;
    113 //        CGFloat downloadY = labelH + labelY;
    114 //        UIButton *downloadBtn = [[UIButton alloc]init];
    115 //        downloadBtn.frame = CGRectMake(downloadX, downloadY, downloadW, downloadH);
    116 //        //downloadBtn.backgroundColor = [UIColor yellowColor];
    117 //        //设置背景图片
    118 //        [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen"] forState:UIControlStateNormal];
    119 //        [downloadBtn setBackgroundImage:[UIImage imageNamed:@"buttongreen_highlighted"] forState:UIControlStateHighlighted];
    120 //        //设置字体第一种方法
    121 //        [downloadBtn setTitle:@"下载" forState:UIControlStateNormal];
    122 //        
    123 //        //设置字体第二种方法(不推荐使用)
    124 //        downloadBtn.titleLabel.text = @"下载";
    125 //        
    126 //        //设置字体大小
    127 //        downloadBtn.titleLabel.font = [UIFont systemFontOfSize:15];
    128 //        [appView addSubview:downloadBtn];
    129 //        
    130 //        
    131 //        [downloadBtn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];
    132     }
    133     
    134  
    135     
    136     
    137     
    138 }
    139 /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/
    140 /**
    141  *  按钮的点击方法
    142  *
    143  *  @param btn 将按钮本身传入方法中,哪个按钮被点击就调用这个方法
    144  */
    145 - (void)btnOnClick:(UIButton *)btn{
    146 
    147     //NSLog(@"------%@",btn);
    148     btn.enabled = NO;
    149     [btn setTitle:@"已下载" forState:UIControlStateNormal];
    150     
    151     CGFloat labelW = 120;
    152     CGFloat labelH = 30;
    153     CGFloat labelX = (self.view.frame.size.width - labelW)* 0.5;
    154     CGFloat labelY = (self.view.frame.size.height - labelH)*0.5;
    155     UILabel *label = [[UILabel alloc]init];
    156     label.frame = CGRectMake(labelX, labelY, labelW, labelH);
    157     label.text = @"正在下载";
    158     //设置字体颜色
    159     label.textColor = [UIColor redColor];
    160     //设置字体居中
    161     label.textAlignment = NSTextAlignmentCenter;
    162     //设置 背景色
    163     label.backgroundColor = [UIColor blackColor];
    164     
    165     //设置圆角的半径
    166     label.layer.cornerRadius = 8;
    167     //将多余的部分减掉
    168     label.layer.masksToBounds = YES;
    169     //设置透明度
    170     label.alpha = 0.0;
    171     //将label添加到view中
    172     [self.view addSubview:label];
    173     //使用block动画,动画持续时间2秒
    174     [UIView animateWithDuration:2.0 animations:^{
    175         label.alpha = 0.5;
    176     } completion:^(BOOL finished) {
    177         if (finished) {
    178             [UIView animateWithDuration:2.0 delay:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
    179                 label.alpha = 0.0;
    180             } completion:^(BOOL finished) {
    181                 //上面将透明度设置为0,界面上已经不显示这个label,但是它仍然在内存中,所以为了节约内存,仍要将其从内存中删除
    182                 [label removeFromSuperview];
    183                 
    184             }];
    185         }
    186     }];
    187     
    188 }
    189 /**
    190  *  "懒加载",加载应用数据
    191  *
    192  */
    193 - (NSArray *)apps{
    194 
    195     //如果_apps为空,才加载数据
    196     if (_apps == nil) {
    197         //获取plist的全路径
    198         NSString *path = [[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil];
    199 
    200         //加载数组
    201         NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
    202         
    203         //创建一个可变数组,来动态接收模型对象
    204         NSMutableArray *array = [NSMutableArray array];
    205         
    206         //通过循环,将字典数组的字典取出,转成模型对象
    207         for (NSDictionary *dict in dictArray) {
    208             KZAppModel *appModel = [KZAppModel appWithModelDict:dict];
    209             [array addObject:appModel];
    210         }
    211         _apps = array;
    212     }
    213     return _apps;
    214     /*吃唐僧肉的小悟空-转载请注明出处http://www.cnblogs.com/hukezhu/*/
    215 }
    216 
    217 - (void)didReceiveMemoryWarning {
    218     [super didReceiveMemoryWarning];
    219     // Dispose of any resources that can be recreated.
    220 }
    221 
    222 @end

      

      xib文件加载的两种方式:

      

    1 //方法1:
    2 NSArray *objs = [[NSBundle mainBundle] loadNibNamed:@"KZAppView" owner:nil options:nil];
    3 //这个方法会创建xib中的所有对象,并且将对象按顺序放到objs数组中
    4 
    5 
    6 //方法2
    7 //bundle参数可以为nil,默认就是main bundle
    8 UINib *nib = [UINib nibWithNibName:@"KZAppView" bundle:[NSBundle mainBundle]];
    9 NSArray *objs = [nib instantiateWithOwner:nil options:nil];

      获取xib中的控件有两种方式:

        1.通过绑定tag来实现

        2.利用subviews[index];的特性实现

        注意:两种方式都需要强制类型转换

      总结:分析本文中的实现代码,在控制器中使用了xib进行赋值,当然在这里只有一个控制器,假设开发过程中有多个控制器,每个控制器都要使用这个xib,那么每个控制器都要使用这些赋值语句在各自的控制器中实现,假设以后要增加控件或者修改,则需要在每个控制器中都要修改,不利于扩展,所以我们考虑将xib进行封装,使用xib时直接调用即可,假设有修改时,直接修改xib封装的文件,对于调用者没有影响.如下图:

      

      所以,下篇文章再次进行改进,将xib进行封装.

  • 相关阅读:
    前端笔记7
    前端笔记6
    列表、行块元素
    我的学习方法(5)
    (读后摘抄)《计算机程序设计语言的发展》_王汝传
    电影《比利·林恩的中场战事》
    关于优化(1)
    Debug技巧(1)
    奇奇怪怪的东西(1)
    我的学习方法(4)
  • 原文地址:https://www.cnblogs.com/hukezhu/p/4506001.html
Copyright © 2020-2023  润新知