zoukankan      html  css  js  c++  java
  • ios控件自定义指引

    转载自:http://bbs.9ria.com/thread-256747-1-1.html

    一直以来都想写点什么,做点有意义的事,从今天开始我将会把自己在这一年的学习和应用IOS开发中的学习心得和体会写出来,我将更深入的让大家理解IOS开发的方方面面,不过仍不能保证涉及所有的范围,希望我的理解可以给一些初学者一些帮助。 

    白天上班没有时间,而且公司上不了网 , 哎 伤不起~ 
    对于IOS的UI开发,我不想讨论什么什么控件该怎样使用,平时有些人会问我,怎么用,我只能说我也不会,我只是去试验,去找方法,如果你连控件都不能熟悉使用那我只能说你不够下功夫,或者说你还是没有领会IOS开发的精髓,如果你懂了,真正理解了,那么我相信,没有你不会的控件,我要说的第一部分就是IOS的UI开发,不过我会换一个方式让大家更深的去理解去应用它。 

    好了,首先我想先说UI控件的三要素,请记住:绘制、数据、控制,有没有听过?也许没有,这只是我的个人总结而已,为什么是这3个,首先,展现在我们视线里的是可见的,那就是绘制,每一个控件都有自己的样子,就跟人的相貌一样,比如TableView是一张数据表,又比如datePicker是一个时间选择器,他们的样子都是不一样的; 

    然后是数据,控件也需要自己的数据,比如label,需要显示文字的数据,比如imageView需要显示图片的数据,如果没有数据这些控件的使用将会变得没有意义; 

    最后一个就是控制了,最典型的就是button了,这是用户与界面交互的关键,还有其他的控件,比如scrollview,可以滑动加载数据,这是控制; 

    好了,3要素都记住了吗?绘制、数据、控制。 

    为什么要说这些,我们的最终目的是什么?就是当我们真正理解了,那么我们就可以自己来定义自己的控件了,Iphone的体验好,其一的原因是因为美观。当然现在你只是理解了有这3个要素而已,现在就开始定义我们的控件有点早,不如拿官方的控件来研究一下,我们来仿照官方的控件,自己来实现它提供的控件,是不是很激动? 

    好,接下来我们一起来做做苹果自己做的事,是不是觉得自己很牛掰了,哈哈 

    自定义UIImageView 
    好,请记住我,我自己的控件不用UI开头,全部以R开头,那么第一个控件就是RImageView 

    所有的视图都是继承自UIView,所以我们的RImageView也是继承自UIView 。记得3要素吗,在次提起一下,绘制,数据,控制,对于ImageView,我们需要绘制,需要提供图片资源,对于控制就不需要了,所以在我们的头文件里我们这样定义  

    @interface RImageView : UIView 
    
    @property(retain,nonatomic)UIImage *image; 
    @end 

    有了数据我们就来绘制吧 

    在我们的.m文件中,找到绘制函数 

    - (void)drawRect:(CGRect)rect 
    { 
    [image drawInRect:rect]; 
    } 

    ok,完成,一个简单的ImageView已经做好了,现在试试看我们自己写的控件是什么样子

    RImageView *imageView = [[RImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    imageView.image = [UIImage imageNamed:@"test.png"]; 
    [self.window addSubview:imageView]; 

    imageView的另一个功能是可以添加图片数组实现动画,我们只要定义一个数组存放图片数组,当执行startAnimation函数时,执行定时器功能,从数组中循环遍历图片进行绘制,stopAnimation时关闭定时器,恢复到默认的imag即可,在此不再深入,感兴趣的同学可以自己去试着写写看。 

    是不是很简单, 千万别说坑爹啊,这只是我们小小的开始,虽然简单了点,但已经能说明问题了,觉得技术含量不够,那我们来写一个经典的吧 

    一个最能说明绘制和数据问题的控件就是label了,想想我们在绘制它的时候需要绘制什么呢?我们需要绘制显示的字体大小,颜色,背景色 

    所以我们的RLabel的头文件应该是这样的

    @interface RLabel : UIView 
    
    @property(retain,nonatomic)NSString *text; 
    @property(retain,nonatomic)UIFont *font; 
    @property(retain,nonatomic)UIColor *color; 
    
    @end 

    在初始化函数里,我们设置默认的绘制参数

    self.font = [UIFont boldSystemFontOfSize:(int)frame.size.height]; 
    color = [UIColor blackColor]; 
    [self setBackgroundColor:[UIColor whiteColor]]; 

    下面是绘制的函数实现

    - (void)drawRect:(CGRect)rect 
    { 
    
    [color setFill]; 
    
    [text drawInRect:rect withFont:font]; 
    
    } 

    使用一下看看

    RLabel *labell = [[RLabel alloc] initWithFrame:CGRectMake(200, 400, 100, 30)]; 
    labell.text = @"123"; 
    [self.window addSubview:labell]; 
    [labell release]; 

    很好,再试试看我们再改一下它的text,labell.text = @"456";没有变,还是原来的显示,没变那是对的,变了才奇怪呢。还记得我说过的3要素吗?这里我们更改了数据却没有重新绘制,只要在更改text值的时候,执行一下setNeedsDisplay函数就可以了,那要怎样实现? 

    为了实现刷新的功能我们不得不再回顾一下property和synthesize了,他们的功能等价于setter和getter函数,我们在每一次的setter函数里进行刷新,于是我们去除@property(retain,nonatomic)NSString *text,取而代之的是setter和getter函数声明

    -(void)setText:(NSString *)str; 
    
    -(NSString*)getText; 
    
    @synthesize text就改成了setter和getter的实现 
    -(void)setText:(NSString *)str{ 
    [text release]; 
    text = str; 
    [text retain]; 
    [self setNeedsDisplay]; 
    } 
    
    -(NSString*)getText{ 
    return text; 
    } 

    注意setter函数的release和retain,这正是retain属性的原型,好了,我们再来试试,这样我们的自定义label已完成了它最基本的功能,label还有其他的属性,大家可以自己添加完善自己的label 

    自定义UIButton 
    一个最能说明控制的控件就是经典的button了,来写我们的RButton吧,先事先想想Button有哪些属性? 
    为了简单起见,我们绘制roundrectButton就可以了,那么就有点击的效果,点击完的效果,点击的事件 

    定义一下我们的头文件

    @interface RButton : UIView{ 
    id _delegate; 
    UIControlEvents controlEvent; 
    SEL methodAction; 
    } 
    
    - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; 
    @end 

    在这个方法里,我们将传递的所有信息都给了button,接下来就是完成事件点击了 ,为了更好的体现点击的效果,我们需要绘制,很简单,设置一下背景色就可以了 。在初始化函数里 [self setBackgroundColor:[UIColor grayColor]]; 
    然后就是touch事件了,根据选择的touch类型,这里只介绍两种类型:UIControlEventTouchDown和UIControlEventTouchUpInside 
    第一个手势是在begin的时候就会处理

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
    if (controlEvent == UIControlEventTouchDown) { 
    [_delegate performSelector:methodAction withObject:self]; 
    } 
    [self setBackgroundColor:[UIColor blueColor]]; 
    } 

    第二个手势在end时候才会处理

    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 
    if (controlEvent == UIControlEventTouchUpInside) { 
    [_delegate performSelector:methodAction withObject:self]; 
    } 
    [self setBackgroundColor:[UIColor grayColor]]; 
    } 

    当我们为button添加事件的时候我们就已经获取了应该实现哪个手势,这样我们就定义了自己的button,使用和官方的一模一样了,我们来使用一下

    RButton *button = [[RButton alloc] initWithFrame:CGRectMake(150, 300, 60, 40)]; 
    button.tag =11; 
    [button addTarget:self action:@selector(doit:) forControlEvents:UIControlEventTouchUpInside]; 
    [self.window addSubview:button]; 
    
    
    -(void)doit:(id)sender{ 
    NSLog(@"tag == %d",[sender tag]); 
    NSLog(@"oh its good!"); 
    } 

    你可以自己选择是否需要传参数 

    如果大家有兴趣的话可以自己添加比如 
    -(void)setImage:(UIImage*)image forState:(UIControlState)state 
    或者设置title的函数,这里就不实现了

  • 相关阅读:
    http url转义字符,特殊字符
    No bean named 'cxf' is defined
    c语言中结构体指针
    Android fragment (二)
    文件I/O之C标准库函数和系统库函数差别
    计算机组成原理——主存与cache的映射关系
    openstack 用nova API 指定 compute node 创建 instance
    SQL存在一个表而不在还有一个表中的数据
    hdu 2602
    小金登陆游戏
  • 原文地址:https://www.cnblogs.com/benbenzhu/p/3362831.html
Copyright © 2011-2022 走看看