下拉列表框实现

下拉列表框实现,第1张

概述下拉列表框实现 一、实现框架 1 二、实现根视图 1 三、实现DropDownList类 2 四、一些改进 6 cocoa touch不提供下拉框控件,因为他们提供了UIPickerView。为什么还要使用已经成为windows标准控件之一的下拉框呢?“这不是苹果的体验”——“苹果体验”推崇者们这样反对。但作为从windows开发平台转移过来的程序员,他们只需要一个理由就足够反驳了:UIPicke

下拉列表框实现

一、实现框架 1
二、实现根视图 1
三、实现DropDownList类 2
四、一些改进 6

cocoa touch不提供下拉框控件,因为他们提供了UIPickerVIEw。为什么还要使用已经成为windows标准控件之一的下拉框呢?“这不是苹果的体验”——“苹果体验”推崇者们这样反对。但作为从windows开发平台转移过来的程序员,他们只需要一个理由就足够反驳了:UIPickerVIEw太大了,远没有下拉框控件节省屏幕空间。真实情况就是这样的,放一个UIPickerVIEw,足够放3个下拉框都绰绰有余了。
一、实现框架
1、新建一个Window-based-application。
2、新建一个UIVIEwController:RootVIEwController。在其loadVIEw方法中增加:self.vIEw=[[UIVIEwalloc]initWithFrame:
      [[UIScreenmainScreen]bounds]];

3、修改 AppDelegate,加入以下两句并导入相关类,使应用程序启动时加载一个RootVIEwController:
 RootVIEwController* root=[[RootVIEwControlleralloc]init];
 [windowaddSubvIEw:root.vIEw];

二、实现根视图
1、在根视图中添加几个文本框,用来模拟下拉列表框(后面实现),在loadVIEw方法中加入代码:
 //1个textfIEld
 UITextFIEld* tf=[[UITextFIEldalloc]initWithFrame:
     CGRectMake(144,73,140,30)];
 tf.borderStyle=UITextborderStyleRoundedRect;
 [self.vIEwaddSubvIEw:tf];
 [tfrelease];

 //2个textfIEld
 tf=[[UITextFIEldalloc]initWithFrame:
     CGRectMake(144,129,30)];
 tf.borderStyle=UITextborderStyleRoundedRect;
 [self.vIEwaddSubvIEw:tf];
 [tfrelease];
运行效果如下:


2、将上面的UITextFIEld替换为DropDownList。下面,我们准备自己实现这个DropDownList。


三、实现DropDownList类
1、新建UIVIEw子类DropDownList。
2、我们准备用一个文本输入框加上一个tableVIEw控件来实现这个下拉框。在头文件中声明如下,注意相应的 @synthesize语句:
@interfaceDropDownList : UIVIEw {
 UITextFIEld* textFIEld;//文本输入框
 NSArray* List;//下拉列表数据
 BOolshowList;//是否d出下拉列表
 UItableVIEw* ListVIEw;//下拉列表
 CGRectoldFrame,newFrame;//整个控件(包括下拉前和下拉后)的矩形
 UIcolor *linecolor,*ListBgcolor;//下拉框的边框色、背景色
 CGfloatlinewidth;//下拉框边框粗细
 UITextborderStyleborderStyle;//文本框边框style
}
@property (nonatomic,retain)UITextFIEld *textFIEld;
@property (nonatomic,retain)NSArray* List;
@property (nonatomic,retain)UItableVIEw* ListVIEw;
@property (nonatomic,retain)UIcolor *linecolor,*ListBgcolor;
@property (nonatomic,assign)UITextborderStyleborderStyle;
-(voID)drawVIEw;
@end
3、然后在initWithFrame方法中初始化变量, 并调用drawVIEw绘制控件:
if(self=[superinitWithFrame:frame]){
  //默认的下拉列表中的数据
  List=[[NSArrayalloc]initWithObjects:@"1",@"2",@"3",@"4",nil];
  
  borderStyle=UITextborderStyleRoundedRect;
  
  showList=NO; //默认不显示下拉框
  oldFrame=frame; //未下拉时控件初始大小
  //当下拉框显示时,计算出控件的大小。
  newFrame=CGRectMake(frame.origin.x,frame.origin.y,frame.size.wIDth,frame.size.height*5);
  
  linecolor=[UIcolorlightGraycolor];//默认列表边框线为灰色
  ListBgcolor=[UIcolorwhitecolor];//默认列表框背景色为白色
  linewidth=1;     //默认列表边框粗细为1
  
  //把背景色设置为透明色,否则会有一个黑色的边
  self.backgroundcolor=[UIcolorclearcolor];
  [selfdrawVIEw];//调用方法,绘制控件
  
 }
 returnself;
4、先在drawVIEw方法中绘制一个文本框:
 //文本框
 textFIEld=[[UITextFIEldalloc]
   initWithFrame:CGRectMake(0,
          oldFrame.size.wIDth,
          oldFrame.size.height)];
 textFIEld.borderStyle=borderStyle;//设置文本框的边框风格
 [selfaddSubvIEw:textFIEld];
运行程序,进行测试。但我们点击DropDownList控件的输入框时,键盘会自动d出,我们需要屏蔽掉它。在上面的代码后加上:
//增加文本框的触摸事件响应
 [textFIEldaddTarget:selfaction:@selector(dropdown)
  forControlEvents:UIControlEventAlltouchEvents];
然后实现dropdown方法:
-(voID)dropdown{
 [textFIEldresignFirstResponder];
}
现在,键盘不会自动d出了。
5、在drawVIEw方法中添加代码,以绘制tableVIEw控件:
 //下拉列表
 ListVIEw=[[UItableVIEwalloc]initWithFrame:
   CGRectMake(linewidth,oldFrame.size.height+linewidth,
      oldFrame.size.wIDth-linewidth*2,
      oldFrame.size.height*4-linewidth*2)];
 ListVIEw.dataSource=self;
 ListVIEw.delegate=self;
 ListVIEw.backgroundcolor=ListBgcolor;
 ListVIEw.separatorcolor=linecolor;
 ListVIEw.hIDden=!showList;//一开始ListVIEw是隐藏的,此后根据showList的值显示或隐藏

 [selfaddSubvIEw:ListVIEw]; 
 [ListVIEwrelease];
现在我们必须实现tableVIEw的协议方法(别忘记在头文件中声明UItableVIEwDataSource和UItableVIEwDelegate协议):
#pragma mark ListVIEwdataSource method and delegate method
-(NSInteger)tableVIEw:(UItableVIEw *)table numberOfRowsInSection:(NSInteger)section{
 returnList.count;
}
-(UItableVIEwCell*)tableVIEw:(UItableVIEw *)tableVIEwcellForRowAtIndexPath:(NSIndexPath *)indexPath{
 staticnsString *cellid=@"listviewid";
 UItableVIEwCell* cell=[tableVIEwdequeueReusableCellWithIDentifIEr:cellID];
 if(cell==nil){
  cell=[[[UItableVIEwCellalloc]initWithStyle:UItableVIEwCellStyleDefault
         reuseIDentifIEr:cellID]autorelease];
 }
 //文本标签
 cell.textLabel.text=(Nsstring*)[ListobjectAtIndex:indexPath.row];
 cell.textLabel.Font=textFIEld.Font;
 
 cell.selectionStyle=UItableVIEwCellSelectionStyleGray;
 return cell;
}
-(CGfloat)tableVIEw:(UItableVIEw *)tableVIEwheightForRowAtIndexPath:(NSIndexPath *)indexPath{
 returnoldFrame.size.height;
}
//当选择下拉列表中的一行时,设置文本框中的值,隐藏下拉列表
-(voID)tableVIEw:(UItableVIEw *)tableVIEwdIDSelectRowAtIndexPath:(NSIndexPath *)indexPath{
 //NSLog(@"select");
 textFIEld.text=(Nsstring*)[ListobjectAtIndex:indexPath.row];
 //NSLog(@"textField.text=%@",textField.text);
 [selfsetShowList:NO];
}
setShowList是showList变量的setter方法。该方法根据给定的参数隐藏或显示下拉框。showList变量的访问方法如下:
-(BOol)showList{//setShowList:No为隐藏,setShowList:Yes为显示
 returnshowList;
}
-(voID)setShowList:(BOol)b{
 showList=b;
 NSLog(@"showList is set ");
 if(showList){
  self.frame=newFrame;
 }else {
  self.frame=oldFrame;
 }
 ListVIEw.hIDden=!b;
}

运行程序,点击文本框,下拉框没有出来。别急,我们的dropdown方法还没有相关的代码:
 if (showList) {//如果下拉框已显示,什么都不做
  return;
 }else {//如果下拉框尚未显示,则进行显示
  //把dropdownList放到前面,防止下拉框被别的控件遮住
  [self.supervIEwbringSubvIEwToFront:self];
  [selfsetShowList:YES];//显示下拉框
 }
运行程序,点击文本框,下拉列表可以显示了。但是tableVIEw是没有边框的:
 


要为下拉框加上边框,我们需要实现以下方法:
//为tableVIEw加上边框
-(voID)drawRect:(CGRect)rect{
 //NSLog(@"%@",rect);
 CGContextRefctx=UIGraphicsGetCurrentContext();
 CGRectdrawRect;
 if (showList) {
  CGContextSetstrokecolorWithcolor(ctx,[linecolorCGcolor]);
  drawRect=ListVIEw.frame;
  CGContextstrokeRect(ctx,drawRect);
  //CGContextstrokeRectWithWIDth(ctx,drawRect,linewidth);
 }else {
  return;
 }
 //[selfdrawListborder:ctx :drawRect];
}
这个方法会在收到setNeedsdisplay方法时被调用,因此我们需要在显示下拉列表时,发送setNeedsdisplay消息。在setShowList方法最后发送setNeedsdisplay消息:
[selfsetNeedsdisplay];//调用drawRect重绘
运行效果如下:
 


如果我们要在列表中显示自己的数据,可以在构造dropDownList后对List属性赋值:
 DropDownList* tf=[[DropDownListalloc]initWithFrame:
     CGRectMake(144,30)];
 tf.borderStyle=UITextborderStyleRoundedRect;
 tf.textFIEld.placeholder=@"请输入联系方式";
 NSArray* arr=[[NSArrayalloc]initWithObjects:@"电话",@"email",@"手机",nil];
 tf.List=arr;
 [arrrelease];
 [self.vIEwaddSubvIEw:tf];
 [tfrelease];

运行效果如下:
 


四、一些改进
1、使用NSDictionary作为模型数据
由于下拉框选项一般会由两部分的数据构成:显示文本和数据,所以使用由“键-值”对组成的Dictionary类型来表示下拉框的数据模型更为适宜。因此我们把DropDownList的List修改为NSDictionary类型:
Nsstring* data;//变量,存储选中项的key值
NSDictionary* List;//下拉列表数据
NSArray* allKeys;//所有键
⋯⋯
@property (nonatomic,retain)Nsstring* data;
-(voID)setList:(NSDictionary *)val;
⋯⋯
@synthesize data
⋯⋯
List=[[NSDictionarydictionaryWithObjectsAndKeys:
   @"市场部",@"1",@"行政部",nil]retain];
allKeys=[List.allKeysretain];
⋯⋯
-(voID)setList:(NSDictionary *)val{
 List=val;
 allKeys=val.allKeys;
 allKeys.retain;
 [ListVIEwreloadData]; //刷新textVIEw显示
 textField.text=@"";//清空文本框内容,不能让文本框的内容与下拉列表中的内容不一致
}
同时修改tableVIEw数据源方法和委托方法中的代码:
-(UItableVIEwCell*)tableVIEw:(UItableVIEw *)tableVIEwcellForRowAtIndexPath:(NSIndexPath *)indexPath{
⋯⋯
//获得字典中的键和值
 Nsstring* sKey=[List.allKeysobjectAtIndex:indexPath.row];
 Nsstring* sVal=(Nsstring*)[ListobjectForKey:skey];
 //文本标签
 cell.textLabel.tag=sKey;
 cell.textLabel.text=sVal;
 [skeyrelease];
 [sValrelease];
⋯⋯

-(voID)tableVIEw:(UItableVIEw *)tableVIEwdIDSelectRowAtIndexPath:(NSIndexPath *)indexPath{
 //获得字典中的键和值
 data=[allKeysobjectAtIndex:indexPath.row];
 textFIEld.text=(Nsstring*)[ListobjectForKey:data];
 [selfsetShowList:NO];
}
现在仅仅是构造一个DropDownList对象,不用修改什么属性,结果如下:
 


当你选择一个下拉选项后,文本框内的文字会发生改变。
2、定义协议并通过委托进行扩展
仅仅是显示列表供用户选择,而不进行任何动作显然是不够的。我们可以定义一个委托属性,把选择后的动作交给委托来做。
首先,需要在头文件中定义要委托的工作,即协议:
@protocolDropDownListDelegate

@required
-(voID)selected:(Nsstring*)k displayLabel:(Nsstring*)v;
@end
其次,在头文件中定义一个ID属性:
ID<DropDownListDelegate>delegate;//委托,当选定下拉项后处理
⋯⋯
@property (nonatomic,assign)ID<DropDownListDelegate> delegate;

然后在implementation部分@synthesize delegate;
并在-(voID)tableVIEw: dIDSelectRowAtIndexPath:方法中加入:
if (delegate!=nil) {
  [delegateperformSelector:@selector(selected:displayLabel:)
     withObject:datawithObject:textFIEld.text];
 }
回到RootVIEwController,在interface部分,再类名后增加<DropDownListDelegate>
在loadVIEw方法中增加dropList.delegate=self;
最后实现协议中定义的方法:
-(voID)selected:(Nsstring *)k displayLabel:(Nsstring *)v{
 NSLog(@"%@:%@",v);}运行程序,选择下拉项,委托方法(协议方法)会被调用,后台输出如下:2010-08-17 15:13:05.104 DropDownBox[3048:207] 1:市场部2010-08-17 15:13:07.288 DropDownBox[3048:207] 2:行政部2010-08-17 15:13:09.153 DropDownBox[3048:207] 1:市场部2010-08-17 15:13:11.371 DropDownBox[3048:207] 2:行政部通过委托和协议的方式对类进行扩展,与通过子类进行扩展比较而言,显然更加的灵活,代码更为分散。

总结

以上是内存溢出为你收集整理的下拉列表框实现全部内容,希望文章能够帮你解决下拉列表框实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1068717.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存