简单MVC模式demo-应用管理附源码
这是一个应用管理的简单demo 具体效果如下:
demo 使用的知识点如下:
? UIView的常见属性和方法
? 九宫格计算方法
? 字典转模型
? Xib的使用
? 自定义view(view的封装)
? 简单的MVC
模型 Mode : CLApp.m
dict 是一个字典,保存的是应用图标名称,和应用名称
import "CLApp.h" @interface CLApp () @end @implementation CLApp -(instancetype)initWithDict:(id)dict { if (self = [super init]) { _icon = dict[@"icon"]; _name = dict[@"name"]; } return self; } + (instancetype)appWithDict:(id)dict { return [[self alloc]initWithDict:dict]; } @end
因为控制器要控制协调模型,视图,所以代码量是最多,整个应用的业务逻辑体现于此.为了能让控制器的代码足够的简洁,清楚,优雅!所以要尽可能的对Mode和View封装.
控制器Controller: CLViewController.m
#import "CLViewController.h" #import "CLApp.h" #import "CLAppView.h" @interface CLViewController () /** * 存放应用的信息 名称和图标 */ @property (nonatomic, strong) NSArray *apps; @end @implementation CLViewController - (void)viewDidLoad { [super viewDidLoad]; //1.应用的尺寸 CGFloat appW = 85; CGFloat appH = 90; //2.列数 int totalcolumn = 3; //3.间隙 CGFloat marginX = (self.view.frame.size.width - totalcolumn * appW) / (totalcolumn + 1); CGFloat marginY = 25; //4.根据应用个数创建对应框框 for (int index = 0; index < self.apps.count; index++) { //4.1计算格子的X和Y CGFloat appX = (index % totalcolumn) * (appW + marginX) + marginX; CGFloat appY = (index / totalcolumn) * (appH + marginY) + marginY; //4.2创建appView CLAppView *appView = [CLAppView appViewWithApp:self.apps[index]]; [self.view addSubview:appView]; //4.3设置frame appView.frame = CGRectMake(appX, appY, appW, appH); } } -(NSArray *)apps { //获取主目录 NSBundle *bundle = [NSBundle mainBundle]; //获取全路径 NSString *path = [bundle pathForResource:@"app" ofType:@"plist"]; // //加载数组 // _apps = [NSArray arrayWithContentsOfFile:path]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *appArray = [NSMutableArray array]; for (NSDictionary *dict in dictArray) { //CLApp *app = [[CLApp alloc]initWithDict:dict]; CLApp *app = [CLApp appWithDict:dict]; [appArray addObject:app]; } _apps = appArray; return _apps; } @end
使用Xib文件描述局部界面 如下图:
视图 View :CLAppView
#import "CLAppView.h" @interface CLAppView () - (IBAction)btnClick; @end @implementation CLAppView - (void)setApp:(CLApp *)app { _app = app; //设置图标 self.iconView.image = [UIImage imageNamed:app.icon]; //2.设置名称 self.name.text = app.name; } - (instancetype) initWithApp: (CLApp *)app { NSBundle *bundle = [NSBundle mainBundle]; NSArray *objs = [bundle loadNibNamed:@"CLAppView" owner:nil options:nil]; CLAppView *appView = [objs lastObject]; appView.app = app; return appView; } + (instancetype) appViewWithApp: (CLApp *)app { CLAppView *appView = [[CLAppView alloc]initWithApp:app]; return appView; } - (IBAction)btnClick { CGFloat btnW = 80; CGFloat btnH = 20; CGFloat btnX = (self.superview.superview.frame.size.width - btnW) * 0.5; CGFloat btnY = (self.superview.superview.frame.size.height - btnH) * 0.5; _info = [[UILabel alloc]initWithFrame:CGRectMake(btnX, btnY, btnW, btnH)]; _info.text = self.name.text; _info.backgroundColor = [UIColor greenColor]; _info.textAlignment = NSTextAlignmentCenter; _info.alpha = 0.7; _info.contentMode = UIViewContentModeCenter; CGSize infoSize = [_info.text sizeWithFont:_info.font constrainedToSize:CGSizeMake(320, btnH)]; _info.bounds = CGRectMake(btnX, btnY, infoSize.width, btnH); [UIView animateWithDuration:2 animations:^{ _info.alpha = 0; }]; [self.superview addSubview:_info]; } @end
注意点:
1. 用模型取代字典的好处
? 使用字典的坏处
? 一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编译器不会有任何友善提示,需要手敲
dict[@"name"] = @"Jack";
NSString *name = dict[@"name"];
? 手敲字符串key,key容易写错
? Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据
? 使用模型的好处
? 所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业
? 模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
? 使用模型访问属性时,编译器会提供一系列的提示,提高编码效率
app.name = @"Jack”;
NSString *name = app.name;
l 字典转模型的过程最好封装在模型内部
l 模型应该提供一个可以传入字典参数的构造方法
- (instancetype)initWithDict:(NSDictionary *)dict;
l + (instancetype)xxxWithDict:(NSDictionary *)dict;
2. instancetype
instancetype在类型表示上,跟id一样,可以表示任何对象类型
instancetype只能用在返回值类型上,不能像id一样用在参数类型上
instancetype比id多一个好处:编译器会检测instancetype的真实类型
3. Xib文件的使用
Xib文件可以用来描述某一块局部的UI界面
Xib文件的加载
? 方法1
NSArray *objs = [[NSBundle mainBundle] loadNibNamed:@"MJAppView" owner:nil options:nil];
这个方法会创建xib中的所有对象,并且将对象按顺序放到objs数组中
(如果xib如右图所示,那么objs数组中依次会有3个对象:1个UIView、1个UIButton、1个UISwitch)
? 方法2
bundle参数可以为nil,默认就是main bundle
UINib *nib = [UINib nibWithNibName:@"MJAppView" bundle:[NSBundle mainBundle]];
NSArray *objs = [nib instantiateWithOwner:nil options:nil];
? 在开发阶段,面向开发者的是xib文件; 当把应用装到手机上时,xib文件就会转为nib文件
4. Xib和storyboard对比
? 共同点:
? 都用来描述软件界面
? 都用Interface Builder工具来编辑
? 不同点
? Xib是轻量级的,用来描述局部的UI界面
? Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
5. view的封装
如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心
外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。