对于自定义控件,我相信是每一个iOS开发或者移动端开发,客户端开发的入门知识之一。那么何为自定义控件?继承自系统自带的控件,写一个属于自己的适用的控件,其目的是为了封装控件内部的一些细节。在这里我只说说纯代码的自定义控件,个人认为很适合菜鸟看的,因为你xib有各种你意想不到的天坑和菜鸟所不能了解的东西,特使对于一些半路出家的,所以纯代码自定义控件是你不二的选择。
那么为什么要自定义控件,从而封装里面的细节呢?1.封装的话,下次直接将封装好的类,直接拿去使用2.封装以后,没有重复代码。同时,对于封装的用途有如下:1以后需要封装一些框架给外界使用的时候 2对于项目扩展性大大提高。其实封装的好处和用途在我们iOS开发中是很基础很重要的。
好吧,直接进入正题,自定义控件封装步骤:
一.创建一个类,也就是自定义控件,建议直接继承自UIView,也可以继承自其他组件(PS就是生成一个类)
二.在新建的自定义的视图类(View)中代码思路如下
1. 定义子控件。在init方法内只管控件内部的创建,但不管frame的初始化,因为外界调用的init方法不一定马上给frame赋值,所以第一次init是frame的值可能为nil
//重写-(instancetype)initWithFrame:(CGRect)frame方法
//init方法内部会自动调用
//-(instancetype)initWithFrame:(CGRect)frame 方法,因此建议
//写这个方法,用于替代-(instancetype)init 方法
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super init]) {
定义子控件(创建以及一些属性的定义)
}
return self;
}
2. 定义位置尺寸(Frame)。重写系统的-(void)layoutSubviews方法,这个方法方法专门用来布局子控件,一般在这里设置子控件的frame,当控件本身的尺寸发生改变的时候,系统会自动调用这个方法。重写此方法内一定要调用[super layoutSubviews]
/**
* 这个方法专门用来布局子控件,一般在这里设置子控件的frame
* 当控件本身的尺寸发生改变的时候,系统会自动调用这个方法
*也就是说,如果控件是固死的,则无需在这个方法里面布局子控件,直接在步骤1中做就行了
*/
-(void)layoutSubviews{
// 一定要调用super方法
[super layoutSubviews];
2.定义位置尺寸(Frame)
}
3. 设置数据。提供一个模型属性,重写模型属性的set方法,在set方法中取出模型属性,给对应的子控件赋值
//举例子
/*
*在需要网络请求的数据或者其他数据的都大同小异,都在模型属性中赋值
*/
-(void)setShop:(HYWShop *)shop{
//赋值
_shop = shop;
self.name.text = self.shop.name;
self.iconView.image = [UIImageimageNamed:self.shop.icon];
}
在自定义控件内还可以添加其他更方便的初始化方法,可以参照apple官方的UIView等主要控件,还可以更高层次的封装,这个等以后我弄明白再谈及。
补充:
第一点: init和initWithFrame(一般在使用代码创建的时候调用)
在调用init的时候,系统会默认调用一次initWithFrame;但在调用initWithFrame不会调用init;所以一般初始化自己的子控件一般都是放在initWithFrame
第二点:
给封装View设置数据的几种方式
(1)直接将属性暴漏在.h文件中:不好,影响封装性,不应该将自己的子控件暴漏在头文件中
(2)提供一个初始化方法(也可以采用这种)
(3)根据tag设置子控件数据:1.因为子控件较少,所以设置比较方便。2.控制器做的东西太多了
(4)提供一个设置模型的方法,将模型传递过去(直接传递一个模型对象给View自己设置值)
(5)提供一个属性,直接使用点语法赋值(一般采用这种)