自定义控件复选框和单选框的实现

来源:互联网 发布:软件介质 编辑:程序博客网 时间:2024/06/07 06:45

我们先实现单个按钮,为了复用,不管单选还是复选按钮都是使用同一个类来实现,为了区别单选还是复选,我们用一个自定义枚举类型CheckButtonStyle属性style来区别,当其值设置为CheckButtonStyleDefault或CheckButtonStyleBox时,为复选按钮:

 当其值设为CheckButtonStyleRadio时,为单选按钮:

当按钮在选中/反选状态间切换时,文字左边的图片自动转换。

整个控件是由一个ImageView、一个Label、一个BOOL变量及其他变量组成,.h文件如下:

typedef enum {

    CheckButtonStyleDefault = 0,

    CheckButtonStyleBox = 1,

    CheckButtonStyleRadio = 2

} CheckButtonStyle;

#import <Foundation/Foundation.h>

 

@interface CheckButton :UIControl {

//UIControl*control;

UILabel* label;

UIImageView* icon;

BOOL checked;

id value,delegate;

CheckButtonStyle style;

NSString *checkname,*uncheckname;//勾选/反选时的图片文件名

}

@property (retain,nonatomic)id value,delegate;

@property (retain,nonatomic)UILabel* label;

@property (retain,nonatomic)UIImageView* icon;

@property (assign)CheckButtonStyle style;

-(CheckButtonStyle)style;

-(void)setStyle:(CheckButtonStyle)st;

-(BOOL)isChecked;

-(void)setChecked:(BOOL)b;

@end

具体实现如下:

#import "CheckButton.h"

 

 

@implementation CheckButton

@synthesize label,icon,value,delegate;

-(id)initWithFrame:(CGRect)frame

{

if (self=[super initWithFrame:frame]) {

icon=[[UIImageView alloc]initWithFrame:

  CGRectMake(10, 0, frame.size.height, frame.size.height)];

[self setStyle:CheckButtonStyleDefault];//默认风格为方框(多选)样式

//self.backgroundColor=[UIColor grayColor];

[self addSubview:icon];

label=[[UILabel alloc]initWithFrame:CGRectMake(icon.frame.size.width+24, 0,

  frame.size.width-icon.frame.size.width-24,

  frame.size.height)];

label.backgroundColor=[UIColor clearColor];

label.font=[UIFont fontWithName:@"Arial" size:20];

label.textColor=[UIColor

 colorWithRed:0xf9/255.0

 green:0xd8/255.0

 blue:0x67/255.0

 alpha:1];

label.textAlignment=UITextAlignmentLeft;

[self addSubview:label];

[self addTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];

}

return self;

}

-(CheckButtonStyle)style{

return style;

}

-(void)setStyle:(CheckButtonStyle)st{

style=st;

switch (style) {

case CheckButtonStyleDefault:

case CheckButtonStyleBox:

checkname=@"checked.png";

uncheckname=@"unchecked.png";

break;

case CheckButtonStyleRadio:

checkname=@"radio.png";

uncheckname=@"unradio.png";

break;

default:

break;

}

[self setChecked:checked];

}

-(BOOL)isChecked{

return checked;

}

-(void)setChecked:(BOOL)b{

if(b!=checked){

checked=b;

}

if (checked) {

[icon setImage:[UIImage imageNamed:checkname]];

}else {

[icon setImage:[UIImage imageNamed:uncheckname]];

}

}

-(void)clicked{

[self setChecked:!checked];

if (delegate!=nil) {

SEL sel=NSSelectorFromString(@"checkButtonClicked");

if([delegate respondsToSelector:sel]){

[delegate performSelector:sel];

} 

}

}

-(void)dealloc{

value=nil;delegate=nil;

[label release];

[icon release];

[super dealloc];

}

@end

使用CheckButton类很简单,构造、设置标签文本等属性,然后addSubview:

CheckButton* cb=[[CheckButton alloc] initWithFrame:CGRectMake(20, 60, 260, 32)];

cb.label.text=@"checkbutton1";

cb.value=[[NSNumber alloc]initWithInt:18];

cb.style=CheckButtonStyleDefault;

[self.view addSubview:cb];

二、单选按钮组的实现

复选按钮无所谓“组”的概念,单选按钮则不同。在同一个组中,单选按钮只允许同时选择一个按钮,不能选多个,因此我们要实现一个单选按钮组的类:

#import <Foundation/Foundation.h>

#import "CheckButton.h"

 

@interface RadioGroup : NSObject{

NSMutableArray* children;

NSString* text;

id value;

}

@property (readonly)NSString* text;

@property (readonly)id value;

-(void)add:(CheckButton*)cb;

-(void)checkButtonClicked:(id)sender;

@end

#import "RadioGroup.h"

 

 

@implementation RadioGroup

@synthesize text,value;

-(id)init{

if (self=[super init]){

children=[[NSMutableArray alloc]init];

}

return self;

}

-(void)add:(CheckButton*)cb{

cb.delegate=self;

if (cb.checked) {

text=cb.label.text;

value=cb.value;

}

[children addObject:cb];

}

-(void)checkButtonClicked:(id)sender{

CheckButton* cb=(CheckButton*)sender;

if (!cb.checked) {

//实现单选

for(CheckButton* each in children){

if (each.checked) {

[each setChecked:NO];

}

}

[cbsetChecked:YES];

//复制选择的项

text=cb.label.text;

value=cb.value;

}

NSLog(@"text:%@,value:%d",text,[(NSNumber*)value intValue]);

}

-(void)dealloc{

[text release];

value=nil;

[children release];

[super dealloc];

}

@end

单选按钮组在ViewController中的使用:

-(id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil{

if(self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]){

//单选按钮组

rg=[[RadioGroup alloc]init];

//1个单选按钮

CheckButton* cb=[[CheckButton alloc]initWithFrame:CGRectMake(20, 60, 260, 32)];

//把单选按钮加入按钮组

[rg add:cb];

cb.label.text=@"★";

cb.value=[[NSNumber alloc]initWithInt:1];

//把按钮设置为单选按钮样式

cb.style=CheckButtonStyleRadio;

//加入视图

[self.view addSubview:cb];

[cbrelease];//add后,会自动持有,可以释放

//2个单选按钮

cb=[[CheckButton alloc]initWithFrame:CGRectMake(20, 100, 260, 32)];

[rg add:cb];

cb.label.text=@"★★";

cb.value=[[NSNumber alloc]initWithInt:2];

cb.style=CheckButtonStyleRadio;

[self.view addSubview:cb];

[cbrelease];

//3个单选按钮

cb=[[CheckButton alloc]initWithFrame:CGRectMake(20, 140, 260, 32)];

//各种属性必须在[rg addv]之前设置,否则textvalue不会被populate

cb.checked=YES;

cb.label.text=@"★★★";

cb.value=[[NSNumber alloc]initWithInt:3];

cb.style=CheckButtonStyleRadio;

[self.view addSubview:cb];

[rg add:cb];//属性设置完之后再add

[cbrelease];

//4个单选按钮

cb=[[CheckButton alloc]initWithFrame:CGRectMake(20, 180, 260, 32)];

[rg add:cb];

cb.label.text=@"★★★★";

cb.value=[[NSNumber alloc]initWithInt:4];

cb.style=CheckButtonStyleRadio;

[self.view addSubview:cb];

[cbrelease];

//5个单选按钮

cb=[[CheckButton alloc]initWithFrame:CGRectMake(20, 220, 260, 32)];

[rg add:cb];

cb.label.text=@"★★★★★";

cb.value=[[NSNumber alloc]initWithInt:5];

cb.style=CheckButtonStyleRadio;

[self.view addSubview:cb];

[cbrelease];

}

return self;

}

运行效果: