[ios]自定义UI
参考:http://blog.sina.com.cn/s/blog_7b9d64af0101edqf.html
- (void) showSectionListbyCount:(float)totalCount everyColCount:(float)paramColCount{
int curNum=1;
int TotalRow= ceilf(totalCount/paramColCount);// 总行数
for (int curRow=0; curRow
for (int curCol=0; curCol// 列数
if (totalCount
return;
}
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(10+(67+10)*curCol, (30+10)*curRow, 67, 30)];
[btn setTitle:[NSString stringWithFormat:@"%d",curNum]forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_tv_n"]forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_tv_h"]forState:UIControlStateHighlighted];
[btn setTitleColor:[UIColor blackColor]forState:UIControlStateNormal];
[btn setTitleColor:[UIColor whiteColor]forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(ClickControlAction:)forControlEvents:UIControlEventTouchUpInside];
[btn setTag:curNum];
[self.view addSubview:btn];
curNum++;
}
}
}
如果,我们想用表格,那么每个元素可以使用UITableViewCell来定义相近的项。
很简单是吧,因为,xCode,为我们提供了这些UI控件供我们使用!所以,我们只需要用!
那么,今天的问题也就来了!如果,我想搞一个能够满足自己的一些UI元素。别急,也就是这样:
比如,我要搞这么一个界面!
我想,首先可以肯定,苹果不可能为我量身定制了这么一个控件。并且,如果,我用苹果的默认控件来写,那么我肯定会崩溃的。。
也就是说,我们将每一项,写成单独的一个UI控件。那么,可以根据数据进行填充!那就酷毙了!
绕了,一大圈,也就是要引用出来今天要学习的,东西!
自定义UI!!!
说起来,很牛X。其实很简单,说白了,就是子类化(重写)UIView。
我们常常重写,UIButton,UIImageView,UITableView 等等。因为,可能我们用到的跟这些已有控件很相似,稍微修改一些就能够满足我们。
但是,出入大的时候,我们就不能简单的继承于一个已有控件了!
那就是完全重写!就是子类化UIView。
开始动手吧!!!
1.定义一UIView个的子类。
这个不解释!
2.重写drawRect方法。或者重写layoutSubviews方法、
1. drawRect方法:
- (void)drawRect:(CGRect)rect
{
// Drawing code
for (int i=0; i<<span style="color: #2f2fd0">10; i++) {
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(10, 10+i*40, 67, 30)];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_n"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_h"] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(ClickControlAction:)forControlEvents:UIControlEventTouchUpInside];
[btn setTag:i];
[self addSubview:btn];
}
}
2. layoutSubviews 方法
- (void)layoutSubviews{
[super layoutSubviews];
[self setBackgroundColor:[UIColor clearColor]];
[_imgPic setFrame:CGRectMake(7, 6, 86, 108)];
[_imgPic setImage:[UIImage imageNamed:[self.dictData objectForKey:@"img_content"]]];
[_imgPic.layer setShouldRasterize:NO];
[_imgPic.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[_imgPic.layer setBorderWidth: 1.0];
[[_imgPic layer] setShadowRadius:2];
[[_imgPic layer] setShadowOpacity:1];
[[_imgPic layer] setShadowColor:[UIColor blackColor].CGColor];
[[_imgPic layer] setShadowOffset:CGSizeMake(0, 1)];
[self addSubview:self.imgPic];
}
可见,这两种方法都可以的。具体的区别,就是drawRect方法和layoutSubviews方法之间的区别了。
但是,经过测试,我发现,应该使用drawRect方法,来完成界面的绘制。因为,如果我们使用的是layoutSubviews方法,那么每一次改变frame的时候,layoutSubviews都将重新执行。显然不科学。
在网上,我看到,大部分例子使用的是drawRect方法,来重绘界面。(绘制界面)
我使用了layoutSubviews方法。在frame改变时,会自动调用。(重定向子视图)
根据需要选择使用哪一种方法!
关于两种方法,在网上搜了一下,总结如下:
layoutSubviews在以下情况下会被调用:
1、init初始化不会触发layoutSubviews。
2、addSubview会触发layoutSubviews。
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
4、滚动一个UIScrollView会触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
7、直接调用setLayoutSubviews。
drawRect在以下情况下会被调用:
1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在 控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量 值).
2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。
以上1,2推荐;而3,4不提倡
drawRect方法使用注意点:
1、 若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate 的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或 者 setNeedsDisplayInRect,让系统自动调该方法。
2、若使用calayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕
3.自定义UIView的初始化方法。
我们常常在UIViewController中,看到initWithNibName方法:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// coding
}
return self;
}
这是xCode给我们定义好的初始化方法。
既然,我们要自定义UIView,那么最好,根据自己的业务逻辑,来完成子类化UIView的初始化方法:
#pragma mark - Initialization 根据业务逻辑,传入数据,初始化自己
- (id)initItemWithFram:(CGRect)frame andData:(NSMutableDictionary *)paramData{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
_dictData=[[NSMutableDictionary alloc] init];
_imgPic=[[UIImageView alloc] init];
_imgCover=[[UIImageView alloc] init];
_btnClick=[[UIButton alloc] init];
_btnDel=[[UIButton alloc] init];
_lblTips=[[UILabel alloc] init];
_lblName=[[UILabel alloc] init];
}
self.dictData=paramData;
return self;
}
+ (id) initItemWithFrame:(CGRect)frame andData:(NSMutableDictionary *)paramData{
WTVTVCollectionItem *tmpInstance=[[WTVTVCollectionItem alloc] initItemWithFram:frameandData:paramData];
return tmpInstance;
}
这样,就可以初始化:
NSMutableArray *items = [NSMutableArray array];
[items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];
[items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];
[items addObject:[WTVTVCollectionItem initItemWithFrame:CGRectMake(10, 10, 100, 150)andData:dict]];
4.为UIView加入一些动画
动画是UI操作的灵魂!给予动画效果,就看上去有神了。
添加动画,一般也用2种方法:
1.重写UIView的方法,在调用时,进行动画操作。
# pragma mark - 重写父类的removeFromSuperview方法,在删除时,使用相应的动画效果
- (void) removeFromSuperview {
[UIView animateWithDuration:0.2 animations:^{
self.alpha = 0.0;
[self setFrame:CGRectMake(self.frame.origin.x+50, self.frame.origin.y+50, 0, 0)];
[_btnDel setFrame:CGRectMake(0, 0, 0, 0)];
}completion:^(BOOL finished) {
[super removeFromSuperview];
}];
}
2.直接在UIView元素上,进行动画对象的添加
- (void) enableEditing {
if (self.isInEditingMode == YES)
return;
// 设置为编辑状态
self.isInEditingMode = YES;
[_btnDel setHidden:NO];
// 开始晃动动画
CATransform3D transform;
// 获取0到x-1之间的整数
if (arc4random() % 2 == 1)
transform = CATransform3DMakeRotation(-0.08, 0, 0, 1.0);
else
transform = CATransform3DMakeRotation(0.08, 0, 0, 1.0);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue valueWithCATransform3D:transform];
animation.autoreverses = YES;
animation.duration = 0.1;
animation.repeatCount = 10000;
animation.delegate = self;
[[self layer] addAnimation:animation forKey:@"wiggleAnimation"];
[(WTVTVSprintBoard*)self.delegate enableEditingMode];
}
5.子类化UIView的交互
如何将操作链接起来!?就是说,在控件外,对我们自定义的控件进行操作?!
也有2种方法:
1.消息
2.代理
总结:
我想,我过多的将思路就可以了,因为业务需求不同,控件的自定义需求也不同,所以,不能用具体来固定!但是,思路是想通的,知道了原理,我们就可以发挥我们的聪明智慧,创造出千变万化的控件来!
希望对你有所帮助!!!
[ios]自定义UI的更多相关文章
- iOS开发UI篇—CAlayer(自定义layer)
		iOS开发UI篇—CAlayer(自定义layer) 一.第一种方式 1.简单说明 以前想要在view中画东西,需要自定义view,创建一个类与之关联,让这个类继承自UIView,然后重写它的Draw ... 
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
		本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ... 
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
		iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文 ... 
- iOS开发UI篇—Quartz2D(自定义UIImageView控件)
		iOS开发UI篇—Quartz2D(自定义UIImageView控件) 一.实现思路 Quartz2D最大的用途在于自定义View(自定义UI控件),当系统的View不能满足我们使用需求的时候,自定义 ... 
- iOS(Swift)学习笔记之SnapKit+自定义UI组件
		本文为原创文章,转载请标明出处 1. 通过CocoaPods安装SnapKit platform :ios, '10.0' target '<Your Target Name>' do u ... 
- iOS之UI组件整理
		作者:神兽gcc 授权本站转载. 最近把iOS里的UI组件重新整理了一遍,简单来看一下常用的组件以及它们的实现.其实现在这些组件都可以通过Storyboard很快的生成,只是要向这些组件能够变得生动起 ... 
- iOS开发——UI进阶篇(十五)Quartz2D介绍
		一.Quartz2D简介 1.什么是Quartz2DQuartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作绘制图形 : 线条\三角形\矩形\圆\弧等绘制文字绘 ... 
- iOS开发UI篇—手写控件,frame,center和bounds属性
		iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4 ... 
- iOS开发UI篇—transframe属性(形变)
		iOS开发UI篇—transframe属性(形变) 1. transform属性 在OC中,通过transform属性可以修改对象的平移.缩放比例和旋转角度 常用的创建transform结构体方法分两 ... 
随机推荐
- SpringMyBatisDay02
			全篇概述:IOC DI 参数值注入 注解依赖注入 1.Spring IOCIOC 全称Inversion Of Control,被翻译成控制反转控制反转指:程序中对象的获取方式 ... 
- Twitter OA prepare: Equilibrium index of an array
			Equilibrium index of an array is an index such that the sum of elements at lower indexes is equal to ... 
- linux phpize
			phpize是什么 1.phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块. 当php编译完后,在bin下面会有phpize这个脚本文件, 在编译你要添加的扩展模块之前, ... 
- Django初级手册4-表单与通用视图
			表单的编写 1. detail.html模版的编写 <h1>{{ poll.question }}</h1> {% if error_message %}<p>&l ... 
- python写一个密码生成器的类,要求有个类变量,统计一下一共生成过多少个密码。  要求有4个方法,1:构造方法 2 实例方法  3 类方法  4 静态方法
			生成指定长度的随机数字密码 生成指定长度的随机字母密码 生成指定长度的随机数字和字母的混合 #encoding=utf-8 import random import string class pa ... 
- 基于Spring Cloud的微服务落地
			微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的微服务 ... 
- 自动对比度的opencv实现
			在http://www.cnblogs.com/Imageshop/archive/2011/11/13/2247614.html 一文中,作者给出了“自动对比度”的实现方法,非常nice 实际实现过 ... 
- 20145302张薇《课程设计》数据恢复——WinHex实践
			20145302张薇<课程设计>数据恢复--WinHex实践 实践内容 使用WinHex破损一个U盘 使用WinHex通过DBR备份数据来修复已损坏U盘 实践详细步骤 1.准备一个文件格式 ... 
- 20145317彭垚《网络对抗》Exp9 Web安全基础实践
			20145317彭垚<网络对抗>Exp9 Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询 ... 
- sqlite3 的一些整理和补充
			一,sqlite3数据库打开时的返回值及其所代表的含义 返回值 描述 返回值 描述 SQLITE_OK=0 返回成功 SQLITE_FULL=13 数据库满,插入失败 SQLITE_ERROR=1 S ... 
