首页 > 学院 > 开发设计 > 正文

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

2019-11-14 19:02:43
字体:
来源:转载
供稿:网友

  [注意]转载请注明出处:http://www.VEVb.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.VEVb.com/hukezhu/*/11 @interface KZAppModel : NSObject12 /**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 KZAppModel12 /*吃唐僧肉的小悟空-转载请注明出处http://www.VEVb.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     //注意此处是self29     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.VEVb.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 //        //从模型对象中取出数据name100 //        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.VEVb.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.VEVb.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 //方法27 //bundle参数可以为nil,默认就是main bundle8 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进行封装.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表