封装View
Purpose: 不让controller 知道的太多.
当一个view有太多subview则需要将其封装
初始化subview:
两种方式:init / initWithFrame / lazy load / Xib
init/initWithFrame最终实现initWithFrame 就可以了,因为调用init方法(如果不重
写的话)系统会同时调用initWithFrame方法
也可以懒加载
也可以直接用Xib
//[UIView alloc]init]对应:
- (instancetype)init {
if (self == [super init]) {
self.backgroundColor = [UIColor orangeColor];
UIView *iconView = [[UIView alloc]init];
[self addSubview:iconView];
}
return self;
}
//[[UIView alloc] initWithFrame: 对应
- (instancetype)initWithFrame:(CGRect)frame {
}
layoutSubviews设置subview的frame
消息循环 如果用init 初始化,frame均为0,所以需要用layoutSubviews方法对 subview的frame进行设置
当该View本身size发生改变会被自动调用(避免重写setframe和setbound)
- (void) layoutSubviews; // -> UIView 一定要调用super方法
专门用来布局UIView的子控件;
空间本身size发生变化就会被调用该方法
一定要调用[super layoutSubviews];
- (void) layoutSubviews {
[super layoutSubViews];
CGFloat width = self.frame.size.width;
CGFloat height = self.frame.size.height;
self.label.frame = CGRectMake(0, 0, width, height);
}
给子控件设置模型数据
方法1. 将子控件@property声明放到.h文件中。但这样不好,暴露了。
方法2. 在.h中设置数据:NSString *name; 然后设置set方法,但这样写的话,扩展性太差了。每次添加新的都要重新添加。
//.h
@property (nonatomic, strong)NSString* name;
//.m
- (void)setName:(NSString*)name {
_name = name;
self.label.text = name;
}
//使用
shopView.name = @"xxx";
方法3. 直接传模型就好了。包涵一切
//.h
@class FBShop;
@interface XXXView : UIView
@property(nonatomic, strong) FBShop* shops;
@end
//.m 重写set方法
- (void) setShop:(FBShop*)shop {
_shop = shop;
self.label.text = shop.name;
self.iconView.iamge = [UIImage iamgeNamed:shop.iconName];
}
update 可以用xib直接创建控件。
xib vs storyboard区别:局部和整体。
initWithCoder
通过Xib创建控件,不会调用init方法,而是调用initWithCoder,再调用
awakeFromNib
Load Xib
获取xib
method 1: xib编译后变为nib
NSArray *objs = [[NSBundle mainBundle] loadNibNamed:@"Test" owner:nil optional:nil];
//访问:objs[index]
FBView *view = objs[2];
method 2: 一个UINib对象就是一个Xib文件
//bundle 默认mainbundle
UINib *nib = [UINib nibWithName:@"Test" bundle:nil];
NSArray *objs = [nib instantiatedWithOwner:nil optional:nil];
FBView *fbview = [objs lastObject];
获取subView
method1: 在XIB中给subview设置tag,再根据tag取出
UILabel* label0 = [fbview viewWithTag:20];
改进代码
FBShopView *shopview = [FBShopView shopView];
在FBShopView 重写构造方法:
+ (instancetype) shopView {
return [[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil optional:nil] lastObject];
}