【转】iOS笔记-自定义控件(OC)
原文网址:http://www.jianshu.com/p/f23862eb7b8a
导读:
iOS开发中,很多时候系统提供的控件并不能很好的满足我们的需求,因此,自定义控件便成为搭建UI界面中必不可少的一部分。本篇博文以笔记的形式,总结了自定义控件的两种方式以及每种方式的实现步骤,虽简略却不简单,因此希望留给读者更多的思考空间。作为入门的编程学习者,独立思考能力和动手编程能力都是至关重要的。在此,希望大家学习愉快,共同进步。
自定义控件之xib方式
xib与storyboard
- 共同点:
- 都用来描述软件界面
- 都用Interface Builder工具来编辑
- 本质都是转换成代码去创建控件
- 不同点:
- Xib是轻量级的,用来描述局部的UI界面
- Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
- 共同点:
Xib的加载方式
- 方式一:通过
mainBundelloadNibNamed:加载NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]` - 方式二:通过
UINibnibWithNibName加载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中加载就会调用这个方法;
awakeFromNibstoryboard/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, ...
随机推荐
- [Poi2011]Meteors 题解
题目大意: 给定一个环,每个节点有一个所属国家,k次事件,每次对[l,r]区间上的每个点点权加上一个值,求每个国家最早多少次操作之后所有点的点权和能达到一个值. 思路: 整体二分(二分答案),对于每个 ...
- SPOJ GNYR09F 数字上的找规律DP
Problem C SPOJ GNYR09F dp题,dp可能刚刚开始对大家来说比较难,但是静下心来分析还是比较简单的: dp(i ,j ,k)表示前i个数中,当前累积和为j,末尾数字为k的 ...
- BZOJ 1221: [HNOI2001] 软件开发【最小费用最大流】
Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...
- [NOIP1998] 提高组 洛谷P1012 拼数
题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4 ...
- GDKOI2018游记
D0 开开心心去酒店,在Vanda,资磁,然而和其他人住的比较远,不资磁. 开开心心打开玩具熊,吓尿了..第四部贼难. 晚上看了看网络流,1点才睡.3点多好像梦到玩具熊被吓醒,4点继续睡,6点起. D ...
- hdu 4971
记忆花搜索 dp #include <cstdio> #include <cstdlib> #include <cmath> #include <set& ...
- java collection集合
集合:用于存储对象的容器.集合中可以存储任意类型的对象,长度可变. 集合和数组的比较 集合和数组都是存储对象的容器,不同的是,数组可以存储基本数据类型(int.short.long.char.Bool ...
- 使用uncss去除无用的CSS
1.安装nodejs,gulp,gulp_uncss 1.1.说明:gulp-uncss 是gulp的一个插件.gulp是基于nodejs,理所当然需要安装nodejs: 1.2.安装:打开nodej ...
- javascript实现 京东淘宝等商城的商品图片大图预览功能(图片放大器)
在京东和淘宝等购买东西的时候,我们会经常预览左侧商品展示图片,把鼠标放到原图,右侧就会有个大图显示出细节.本文将带领大家写一个这样简单的功能! 一.实现原理 当鼠标移入某一图片内部时,图片上部会出 ...
- Cg入门6:函数2
内建函数分为四类: 1.数学函数 2.几何函数 3.纹理函数 4.导数函数:事实上就是片段函数