首页 > 代码库 > UI基础xib的使用及xib的封装
UI基础xib的使用及xib的封装
一:
1、xib和stroryboard
Storyboard 描述软件界面,相对于xib比较重量级,一个stroryboard可以有多个场景。可以描述整个软件的所有界面xib 描述软件界面,一般用来描述一个界面中的某一个部分
本质就是代码创建的
xib的加载过程,从xml中加载进来对界面的描述,并以此创建出来 JSAppView *view = [[JSAppView alloc] init];
View.frame = CGRectMake(0,0,85,90);
UIImageView *imageView = .......;[view addSubView:imageView];
...............
xib和storyboard的共同点都用来描述软件界面
都用Interface Builder工具来编辑都使用xml来存储 对界面的描述
xib和storyboard的区别,查看xib和storyboard的xml代码发现他们的区别仅仅是xib少了
Scenes和viewController
xib是轻量级的,用来描述局部的UI界面stroryboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
2:查看Xcode中storyBoard的xml展示文件
3 补充:、storyBoard或者xib中拖一个UIImageView 上不能拖其他控件到它上面
// 通过xib创建view UIView *subView = [[[NSBundle mainBundle] loadNibNamed:@"LLAppInfoView" owner:nil options:nil] lastObject];
#import <UIKit/UIKit.h>@class LLAppInfo;@interface LLAppInfoView : UIView@property (nonatomic, strong) LLAppInfo *appInfo;+ (instancetype)appInfoView;@end
#import "LLAppInfoView.h"#import "LLAppInfo.h"@interface LLAppInfoView ()@property (weak, nonatomic) IBOutlet UIImageView *iconView;@property (weak, nonatomic) IBOutlet UIButton *downView;@property (weak, nonatomic) IBOutlet UILabel *nameView;- (IBAction)downBtnClick:(UIButton *)sender;@end@implementation LLAppInfoView+ (instancetype)appInfoView{ LLAppInfoView *subView = [[[NSBundle mainBundle] loadNibNamed:@"LLAppInfoView" owner:nil options:nil] lastObject]; return subView;}- (void)setAppInfo:(LLAppInfo *)appInfo{ _appInfo = appInfo; self.iconView.image = [UIImage imageNamed:_appInfo.icon]; self.nameView.text = _appInfo.name;}- (IBAction)downBtnClick:(UIButton *)sender { self.superview.userInteractionEnabled = NO; sender.enabled = NO; UILabel *textLab = [[UILabel alloc] init]; [self.superview addSubview:textLab]; textLab.text = [NSString stringWithFormat:@"%@ 正在下载", _appInfo.name]; textLab.backgroundColor = [UIColor grayColor]; textLab.alpha = 0; textLab.textAlignment = NSTextAlignmentCenter; CGFloat textLabW = 200; CGFloat textLabH = 30; CGFloat textLabX = (self.superview.frame.size.width -textLabW) * 0.5; CGFloat textLabY = (self.superview.frame.size.height - textLabH) * 0.5; textLab.frame = CGRectMake(textLabX, textLabY, textLabW, textLabH); textLab.layer.cornerRadius = 10; textLab.layer.masksToBounds = YES; [UIView animateWithDuration:1.0 animations:^{ textLab.alpha = 0.9; [UIView animateWithDuration:1 delay:5 options:UIViewAnimationOptionAllowUserInteraction animations:^{ textLab.alpha = 0; } completion:^(BOOL finished) { [textLab removeFromSuperview]; self.superview.userInteractionEnabled = YES; }]; }];}@end
数据模型
#import <Foundation/Foundation.h>// 封装数据模型@interface LLAppInfo : NSObject/** 图片 */@property (nonatomic, copy) NSString *icon;/**名称 */@property (nonatomic, copy) NSString *name;#warning instancetype 和 id的区别+ (instancetype)appInfoWithDic:(NSDictionary *)dic;- (instancetype)initWithDic:(NSDictionary *)dic;+ (NSArray *)array;@end
#import "LLAppInfo.h"@implementation LLAppInfo- (instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { self.name = dic[@"name"]; self.icon = dic[@"icon"]; } return self;}+ (instancetype)appInfoWithDic:(NSDictionary *)dic{ return [[self alloc] initWithDic:dic];}+ (NSArray *)array{ NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]; NSArray *dicArray = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *appInfoM = [[NSMutableArray alloc] initWithCapacity:dicArray.count]; for (NSDictionary *dic in dicArray) { [appInfoM addObject:[self appInfoWithDic:dic]]; } return appInfoM;}@end
控制器
#import "ViewController.h"#import "LLAppInfo.h"#import "LLAppInfoView.h"@interface ViewController ()// 1,创建接受模型数据的数组@property (nonatomic, strong) NSArray *appInfos;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建九宫格 [self createView]; }#pragma mark - 创建九宫格- (void)createView{ // 1, // 1,1 列数 int colnumCount = 3; CGFloat subViewWH= 100; CGFloat marginX = (self.view.frame.size.width - 3*subViewWH) / (colnumCount + 1); for (int i = 0; i<self.appInfos.count; i++) { // 计算行、列 int row = i/colnumCount; int col = i%colnumCount; // 通过xib创建view// UIView *subView = [[[NSBundle mainBundle] loadNibNamed:@"LLAppInfoView" owner:nil options:nil] lastObject]; // 通过xib封装的view创建view LLAppInfoView *subView = [LLAppInfoView appInfoView]; [self.view addSubview:subView]; // 确定subView的frame CGFloat subViewX = marginX + (marginX + subViewWH) * col; CGFloat subViewY = 30 + (marginX + subViewWH) * row; subView.frame = CGRectMake(subViewX, subViewY, subViewWH, subViewWH);#warning 将子控件添加到一个定义的view中的好处 LLAppInfo *appInfo = self.appInfos[i]; subView.appInfo = appInfo; // 2,取子控件给子控件赋值(这里有两种方法) /** 1,通过viewWithTag 2,通过subViews */ // 这样写还是有问题,如果有多个控件tag标记太多,而且tag的性能很差 UIImageView *iconView = (UIImageView *)[subView viewWithTag:10]; iconView.image = [UIImage imageNamed:appInfo.icon]; UILabel *nameView =(UILabel *) [subView viewWithTag:20]; nameView.text = appInfo.name; }}#pragma mark - 懒加载模型数据- (NSArray *)appInfos{ if (!_appInfos) {#warning NSBundle // NSLog(@"%@", NSHomeDirectory()); // 1,重plist中读取数据// NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];// NSArray *appInfo = [NSArray arrayWithContentsOfFile:path];// // // _appInfos = appInfo;// NSLog(@"%@", _appInfos); // 直接从封装好的代码中取数据 _appInfos = [LLAppInfo array]; } return _appInfos;}@end
1)使用xib封装一个自定义view的步骤
1、新建一个继承UIView的自定义view,类名AppInfoView2、创建xib(xib的名字和自定义view的名字一样AppInfoView),来描述AppInfoView的内部结构3、修改xib中的UIView的类型改为AppInfoView
4、把xib中控件连线到AppInfoView
5、AppInfoView提供一个模型属性
6、重写模型的set方法,在set方法中给xib中对应的子控件赋值
2)封装的好处
xib中完成的代码 controller得知道xib中具体的控件,产生依赖 为了减少依赖,把xib内部控件的赋值给封装起来
如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部的子控件的创建屏蔽起来,不让外界关心,这样不 管view内部怎么变化外界都不需要知道
UI基础xib的使用及xib的封装