自定义封装视图的两种方式纯代码和xib的区别

在开发的过程中,我们可能会碰到这样的情况,一个试图的内部的控件比较多,并且这个试图在多次出现,那我们就要考虑对其进行相应的封装,报漏外部数据模型,这样我们只需要在请求完毕数据,将数据赋值给相应模型,试图拿到数据对其内部的子控件数据进行赋值。

1,纯代码的封装

1.1,封装的步骤

1.在initWithFrame:方法中添加子控件,创建便利构造器方法,用于调用快速生成试图。

2.在LayoutSubviews方法设置子控件的尺寸,等相关的属性。

3.创建数据模型,通过重新set方法,实现对相应子控件显示数据的赋值。

1.2,代码编写注意点

对于初始化试图系统会先调用initWithFrame,然后再调用LayoutSubviews方法,无论创建对象调用的是init方法还是initWithFrame都会调用initWithFrame方法初始化对象,一般将子控件的初始化放在这个方法里面,针对子控件一般调用的是init方法,一般使用init方法生成试图的时候的frame value默认的为0,如果子控件的frame是依赖于父试图的,在这里设置就会出问题,但是子控件的尺寸不是依赖在这里进行设置也是可以显示的,但是在这设置的只会执行一次,当父视图的尺寸发生变化,子控件将不会发生随着变化,父视图的位置被修改就会走LayoutSubview方法,所以需要在这里进行子控件位置确定,并且在确定子控件位置的时候相对于父视图进行设置。使用纯代码不会走initWithCoder和wakeFromNib方法。

1.3,上代码

------ 自定控件view的.h文件------


#import#import "DataModel.h"

@interface CustomView : UIView

//数据模型

@property(strong, nonatomic) DataModel * dataModel;

//创建便利构造器,用于外部创建该自定义控件

+ (instancetype)customView;

@end

------ 自定控件view的.m文件------

#import "CustomView.h"
@interface CustomView()
{
  //声明子控件
  UILabel * _titleLable;
}
@end
@implementation CustomView
//构建便利构造器
+ (instancetype)customView
{
  return [[self alloc] init];
}
//重写initWithFrame:方法,初始化控件
- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
      //创建子控件
      _titleLable = [[UILabel alloc] init];
      [self addSubview:_titleLable];
  }
  return self;
}
//重写父类的layoutSubviews,当父控件的Frame发生变化的时候,相对于父控件布局的子控件的Frame也会随着相应的改变
- (void)layoutSubviews
{
  [super layoutSubviews];
  //设置子控件的Frame等
  _titleLable.backgroundColor = [UIColor orangeColor];
  _titleLable.textColor = [UIColor blackColor];
  _titleLable.textAlignment = NSTextAlignmentCenter;
  _titleLable.frame = CGRectMake(0, self.frame.size.height / 2 - 25, self.frame.size.width, 50);
}
//重写set方法,用于给子控件设置数据
- (void)setDataModel:(DataModel *)dataModel
{
  //给成员变量赋值
  _dataModel = dataModel;
  //给子控件赋值
  _titleLable.text = dataModel.name;
}

@end

------ 数据模型.h文件------

#import <Foundation/Foundation.h>

@interface DataModel : NSObject
//模型的数据
@property(strong, nonatomic) NSString * name;
@end

------ 数据模型.m文件------

#import "DataModel.h"

@implementation DataModel

@end

------ 调用自定控件.h文件------

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

------ 调用自定控件.m文件------

#import "ViewController.h"
#import "CustomView.h"
#import "DataModel.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"纯代码封装";
    self.view.backgroundColor = [UIColor whiteColor];
    [self addControls];
}

//添加控件方法
- (void)addControls
{
    //创建数据模型
    DataModel * dataModel = [[DataModel alloc] init];
    dataModel.name = @"测试";
    //生成自定义控件
    CustomView * customer = [[CustomView alloc] init];
    customer.frame = CGRectMake(50, self.view.frame.size.height/2 - 50, self.view.frame.size.width - 100, 100);
    customer.dataModel =dataModel;
    [self.view addSubview:customer];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

2,xib进行封装

2.1,封装的步骤

1.新建自定义控件类,如果没有xib,需要创建相应的xib与之绑定。

2.增加模型属性,通过重新set方法,实现对相应子控件显示数据的赋值。

2.2,代码编写注意点

1.加载xib后,系统会调用initWithCoder然后调用awakeFromNib,然后再调用LayoutSubviews方法,系统调用initWithCoder在进行xib进行解析,在这时,xib一些细节还没加载完毕,对于子控件的初始化一般放在awakeFromNib中,在对于子控件的位置和尺寸的设置也是一般放在LayoutSubviews方法中,这样父视图frame改变时,依赖其父视图的子视图的frame也会相应的变化。使用xib创建不会走initWithFrame方法。

2.当创建xib,拉控件,控件的尺寸无法改变的时候,需要将其size设置为Freefrom。

3.对于Uiview等绑定xib的时候,需要将点击左侧的File's Owner,设置他的类,做法:按住control从File's Owner往下拉到view上松开,点击view,

4.设置clss为相应的试图。

5.[[NSBundle mainBundle] loadNibNamed:@"ChildView" owner:self options:nil]在绑定的view的initWithCoder设置其为该xib的ower。

3,上代码

创建xib,自定义view和子控件
新建xib


1527678533180.jpg

自定义View的类并与类的属性连线


1527677918785.jpg

1527678014050.jpg

设置自定义View为可变的尺寸,View的背景色
1527678245988.jpg

关闭自动布局(Autolayout),才可以在layoutSubviews里重新设置Button的Frame值


1527678352395.jpg

------ 自定控件view的.h文件------

#import <UIKit/UIKit.h>
#import "DataModel.h"
@interface CustomView : UIView
//数据模型
@property(strong, nonatomic) DataModel * dataModel;
//创建便利构造器,用于外部创建该自定义控件
+ (instancetype)customView;
@end

------ 自定控件view的.m文件------


#import "CustomView.h"
@interface CustomView()
//声明子控件
@property (weak, nonatomic) IBOutlet UILabel *titleLable;
@end
@implementation CustomView
//构建便利构造器
+ (instancetype)customView
{
    CustomView *view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
    return view;
}
//重写initWithCoder:方法,初始化控件
- (instancetype)initWithCoder:(NSCoder *)coder{
    self = [super initWithCoder:coder];
    if (self) {
        
    }
    return self;
}

//重写父类的layoutSubviews,当父控件的Frame发生变化的时候,相对于父控件布局的子控件的Frame也会随着相应的改变
- (void)layoutSubviews
{
    [super layoutSubviews];
    //设置子控件的Frame等
    self.titleLable.backgroundColor = [UIColor orangeColor];
    self.titleLable.textColor = [UIColor blackColor];
    self.titleLable.textAlignment = NSTextAlignmentCenter;
    self.titleLable.frame = CGRectMake(0, self.frame.size.height / 2 - 25, self.frame.size.width, 50);
}
//重写set方法,用于给子控件设置数据
- (void)setDataModel:(DataModel *)dataModel
{
    //给成员变量赋值
    _dataModel = dataModel;
    //给子控件赋值
    _titleLable.text = dataModel.name;
}

------ 数据模型.h文件------

#import <Foundation/Foundation.h>

@interface DataModel : NSObject
//模型的数据
@property(strong, nonatomic) NSString * name;
@end

------ 数据模型.m文件------

#import "DataModel.h"

@implementation DataModel

@end

------ 调用自定控件.h文件------

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

------ 调用自定控件.m文件------


#import "ViewController.h"
#import "CustomView.h"
#import "DataModel.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"xib封装";
    self.view.backgroundColor = [UIColor whiteColor];
    [self addControls];
}

//添加控件方法
- (void)addControls
{
    //创建数据模型
    DataModel * dataModel = [[DataModel alloc] init];
    dataModel.name = @"测试";
    //生成自定义控件
    CustomView * customView = [CustomView customView];
    customView.frame = CGRectMake(0, 200, self.view.frame.size.width
                                    , 100);
    
     customView.dataModel =dataModel;
    [self.view addSubview:customView];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

3,在xib中使用另外一个xib封装

直接上代码

------ 调用自定控件.h文件------

#import <UIKit/UIKit.h>

@interface supView : UIView

@end

------ 调用自定控件.m文件------

#import "supView.h"
@interface supView()
//声明IBOutlet view的变量
@property (strong, nonatomic) IBOutlet UIView *view;

@end
@implementation supView
//重新,当走其他xib中创建class supView的UIview的时候会走这个方法
- (instancetype)initWithCoder:(NSCoder *)coder{
    self = [super initWithCoder:coder];
    if (self) {
        [self setUI];
    }
    return self;
}

- (void)setUI{
//将xib与自身相绑定
    [[NSBundle mainBundle] loadNibNamed:@"supView" owner:self options:nil];
    [self addSubview:self.view];
    self.frame = self.bounds;
}


@end

点击左侧的File's Owner,设置他的类(此处为ChildView),按住control从File's Owner往下拉到View松开,这是会出现Outlets,点击view进行一下关联。(往下拉要出现Outlets,需要先声明IBOutlet view的变量)

1527680742491.jpg

向testViewController.xib中添加UIView控件,该UIView的class属性设置为supView,及关联到自定义的试图,设置约束条件即可。

1527681338854.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容