【转】iOS笔记-自定义控件(OC)
原文网址:http://www.jianshu.com/p/f23862eb7b8a
导读:
iOS开发中,很多时候系统提供的控件并不能很好的满足我们的需求,因此,自定义控件便成为搭建UI界面中必不可少的一部分。本篇博文以笔记的形式,总结了自定义控件的两种方式以及每种方式的实现步骤,虽简略却不简单,因此希望留给读者更多的思考空间。作为入门的编程学习者,独立思考能力和动手编程能力都是至关重要的。在此,希望大家学习愉快,共同进步。
自定义控件之xib方式
xib与storyboard
- 共同点:
- 都用来描述软件界面
- 都用Interface Builder工具来编辑
- 本质都是转换成代码去创建控件
- 不同点:
- Xib是轻量级的,用来描述局部的UI界面
- Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
- 共同点:
Xib的加载方式
- 方式一:通过
mainBundel
loadNibNamed:
加载NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]`
- 方式二:通过
UINib
nibWithNibName
加载UINib *nib = [UINib nibWithNibName:@"xib文件名" bundle:nil];
NSArray *views = [nib instantiateWithOwner:nil options:nil];
- 方式一:通过
通过xib创建自定义控件步骤:
- 新建一个继承
UIView
的类 - 新建一个xib文件(xib的文件名最好跟控件类名一样)
- 添加子控件、设置子控件属性
- 修改最外面那个控件的class为控件类名
- 将子控件进行连线
- 提供模型属性,重写模型的set方法
- 在set方法中给子控件设置数据
- 新建一个继承
示例代码:
- (void)viewDidLoad {
//1.通过mainbundel获取xib文件,返回组件数组
NSArray * viewArr = [[NSBundle mainBundle] loadNibNamed:@"CYXView" owner:nil options:nil];
//2.取出数组中需要的控件
CYXView * myView = (CYXView *)[viewArr lastObject];
//3.设置控件的Frame
myView.frame = CGRectMake(100, 100, 10, 200);
//4.控件添加到self.View中
[self.view addSubview:myView];
}
补充:
initWithcoder
- 只要是从storyboard/xib中加载就会调用这个方法;
这个方法一般是初始化的操作
- 只要是从storyboard/xib中加载就会调用这个方法;
awakeFromNib
storyboard/xib
中加载完毕的时候调用,想做一些在xib加载完毕的操作,就在这个方法中操作(建议在这个方法中写初始化代码)
自定义控件之纯代码方式
- 何为自定义控件?
- 继承自系统自带的控件,写一个属于自己的控件
目的:封装控件内部的细节
为什么要封装?
- 封装的话,下次直接将封装好的类,直接拿去使用
封装以后,没有重复代码
- 封装的话,下次直接将封装好的类,直接拿去使用
- 自定义控件封装步骤:
- 创建一个自定义控件,建议直接继承自UIView,也可以继承自其他组件
封装的用途
- 以后需要封装一些框架给外界使用的时候
对于项目扩展性大大提高
- 以后需要封装一些框架给外界使用的时候
示例代码思路:
在新建的
CYXShopView
视图类(View)中代码思路如下- 1.定义子控件。在
init
方法内只管控件内部的创建,但不管frame
的初始化,因为外界调用的init方法不一定马上给frame
赋值,所以第一次init
是frame
的值可能为nil
- 2.定义位置尺寸(Frame)。重写系统的
-(void)layoutSubviews
方法,这个方法方法专门用来布局子控件,一般在这里设置子控件的frame
,当控件本身的尺寸发生改变的时候,系统会自动调用这个方法。重写此方法内一定要调用[super layoutSubviews]
- 3.设置数据。提供一个模型属性,重写模型属性的set方法,在set方法中取出模型属性,给对应的子控件赋值
- 1.定义子控件。在
在自定义控件内还可以添加其他更方便的初始化方法,可以参照apple官方的
UIView
等主要控件,还可以更高层次的封装,这个等以后再谈及。
//重写-(instancetype)initWithFrame:(CGRect)frame方法
//init方法内部会自动调用-(instancetype)initWithFrame:(CGRect)frame 方法,因此建议写这个方法,用于替代-(instancetype)init 方法
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super init]) {
//添加图片
UIImageView * iconView = [[UIImageView alloc]init];
iconView.backgroundColor = [UIColor grayColor];
[self addSubview:iconView];
//添加文字
UILabel * name = [[UILabel alloc]init];
name.backgroundColor = [UIColor greenColor];
name.font = [UIFont systemFontOfSize:15];
name.textAlignment = NSTextAlignmentCenter;
[self addSubview:name];
}
return self;
}
/**
* 这个方法专门用来布局子控件,一般在这里设置子控件的frame
* 当控件本身的尺寸发生改变的时候,系统会自动调用这个方
*/
-(void)layoutSubviews{
// 一定要调用super方法
[super layoutSubviews];
CGFloat shopW = self.frame.size.width;
CGFloat shopH = self.frame.size.height;
self.iconView.frame = CGRectMake(0, 0, shopW, shopW);
self.name.frame = CGRectMake(0, shopW, shopW, shopH-shopW);
}
-(void)setShop:(CYXShop *)shop{
//赋值
_shop = shop;
self.name.text = self.shop.name;
self.iconView.image = [UIImage imageNamed:self.shop.icon];
}
- 补充:
init
和initWithFrame
(一般在使用代码创建的时候调用- 在调用
init
的时候,系统会默认调用一次initWithFrame
;但在调用initWithFrame
不会调用init
;所以一般初始化自己的子控件一般都是放在initWithFrame
- 在调用
给封装View设置数据的几种方式
(1)直接将属性暴漏在.h文件中:不好,影响封装性,不应该将自己的子控件暴漏在头文件中
(2)提供一个初始化方法
(3)根据tag设置子控件数据
- 因为子控件较少,所以设置比较方便。
- 控制器做的的太多了
(4)提供一个设置模型的方法,将模型传递过去(直接传递一个模型对象给View自己设置值)
(5)提供一个属性,直接使用点语法赋值(最终采取的方法)
【转】iOS笔记-自定义控件(OC)的更多相关文章
- iOS开发(OC)中的命名规范
开小差:最近发现自己有一个经验主义的毛病,不太容易接受新的知识,这对从事技术研发的人来说不太合理,需要改之. 正文:通过读写大量代码我有自己的一套编程思路和习惯,自认为自己的编码习惯还是不错的,代码结 ...
- iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController)
iOS开发——实战OC篇&环境搭建之Xib(玩转UINavigationController与UITabBarController) 前面我们介绍了StoryBoard这个新技术,和纯技术 ...
- iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController)
iOS开发——实战OC篇&环境搭建之纯代码(玩转UINavigationController与UITabBarController) 这里我们就直接上实例: 一:新建一个项目singleV ...
- iOS谋职之OC面试题
iOS谋职之OC面试题 iOS求职之OC面试题 IOS求职之OC面试题 1.Objective-C的类可以多重继承么?可以采用多个协议么? 答:不可以多重继承,可以采用多个协议. 2.#import和 ...
- IOS开发-OC学习-常用功能代码片段整理
IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是 ...
- 【iOS系列】-oc中特有的语法
[iOS系列]-oc中特有的语法 oc数据类型: 1,基本类型 2,对象类型 3,id 4,BOOL 5,block 6,SEL 1:category 使用继承关系来扩充一个类,有一个弊病,高耦合性 ...
- Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮
原文:Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮 上面就是几张预览图!代码在最底下 主要就两个步骤,画图.监听点击 1.整个控件基本上是一步步画出来的,重写onDraw方法开始 ...
- 荼菜的iOS笔记--UIView的几个Block动画
前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...
- iOS 阶段学习第11天笔记(OC基础知识)
iOS学习(OC语言)知识点整理 一.OC基础知识 1)#import 用于导入头文件,预处理阶段加载引用,只加载一次. 2)OC 依赖于Foundation框架下的头文件Foundation.h, ...
随机推荐
- git学习(一)----基础知识
git是世界上最好用最先进的版本管理系统,那么什么是版本管理系统呢,百度上是这样说的: 举个例子,当你写毕业论文的时候,灵感爆发了修改或者删除了一些内容,但是你还想保留之前的版本,就需要另存为不同的w ...
- 洛谷P1016 旅行家的预算
题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...
- 【贪心】codeforces D. Minimum number of steps
http://codeforces.com/contest/805/problem/D [思路] 要使最后的字符串不出现ab字样,贪心的从后面开始更换ab为bba,并且字符串以"abbbb. ...
- bzoj3572[Hnoi2014] 世界树 虚树+dp+倍增
[Hnoi2014]世界树 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1921 Solved: 1019[Submit][Status][Dis ...
- bzoj 3772 精神污染 主席树+dfs序
精神污染 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 637 Solved: 177[Submit][Status][Discuss] Descri ...
- 汕头市赛srm10 T2
n个数,分组,数Ai要在至少含有Ai个数的组,求最多分多少组. 方法一:大的数应该尽量跟大的在一起,这样才能让小的出现很多很多组,所以从大到小排序,给当前序列中最大的数x分x个数.代码如下: #inc ...
- 仿苹果app下载动画-煎饼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【Scrapy】Selectors
Constructing selectors For convenience,response objects exposes a selector on .selector attribute,it ...
- Linux VPS/server上用Crontab来实现VPS自己主动化
VPS或者server上常常会须要VPS或者server上常常会须要定时备份数据.定时运行重新启动某个服务或定时运行某个程序等等,一般在Linux使用Crontab,Windows以下是用计划任务(W ...
- 淘宝API学习之道:淘宝TOP之API接口接入教程
作为一个中小型站点开发人员,淘宝API的开放大大缩短了站点的开发周期和运作效率.面对海量的数据.开发人员仅仅要细致阅读开发文档,熟悉对应的接口,就能够把数据导入自己的站点,这样就不必望洋兴叹了. 眼下 ...