iPhone 中的下拉菜单,或者说选择器一般演变成了Picker,或者UIActionSheet,而前者虽然使用方便,但是占据了非常大的屏幕空间,无法调整。而后者占据空间也很大,而且使用非常受限,垂直方向只能加6个选项,水平方向只能加4个选项,而且如果自定义控件的话,必须至少有一个默认按钮存在,否则加在上面的自定义控件将无法响应操作,当然你可以自定义一个自己的ActionSheet.
这篇文章就来讲一下如何在屏幕空间受限的iPhone中加入下拉菜单,以使用用户的选项操作,代码是基于一个网友的下拉菜单写的,由于忘记地址了,不过在此表示感谢。
(转载请保留此文字:本文来源:[iphone开发私房菜_5_] iphone中如何实现下拉菜单http://blog.csdn.net/ipromiseu/archive/2011/03/04/6224645.aspx] write by Gray.Luo [email protected])
首先我们先来看一下一个下拉菜单由哪些部分组成,有什么特征。下拉菜单,顾名思义就是点击某一个控件,然后就会出现一个下拉框,这个下拉框中就是可供用户选择的选项。那么一个下拉组件就主要包括两个部分,一是触发控件,点击这个控件就会显示下拉框,当然这个触发控件也充当显示当前选项的角色。另一个就是下拉框,里面罗列了可供用户选择的众多数据。
第一个触发控件其实随便用什么控件都行,只要有点击事件就行,比如UISegmentedControl,UIbutton,UIBarButtonItem 等等都是可以的。而第二个下拉框,为了数据处理方便,我一般都采用UITableView 来做这个下拉框,很是方便。好了,基本的原理都分析了,Action吧!
1.创建一个触发控件:
这个本来不需要讲的,但是还是顺便贴一段吧。如这里我就以segment为例,我还是比较喜欢用segment,因为Nav上面不能随便加UIBarButtonItem,所以我就改用segment。
[c-sharp] view plain copy print ?
- _selectSegment = [[UISegmentedControl alloc]initWithFrame:CGRectMake(x,y,length,height)];
- [_selectSegment insertSegmentWithImage:[UIImage imageNamed:@"current.png"] atIndex:0 animated:YES];
- _selectSegment.segmentedControlStyle = UISegmentedControlStyleBar;
- [_selectSegment addTarget:self action:@selector(selectSegmentAction:)forControlEvents:UIControlEventValueChanged];
- [self.navigationController.navigationBar addSubview:_selectSegment];
- [_selectSegment release];
- _selectSegment.selectedSegmentIndex = -1;
_selectSegment = [[UISegmentedControl alloc]initWithFrame:CGRectMake(x,y,length,height)];[_selectSegment insertSegmentWithImage:[UIImage imageNamed:@"current.png"] atIndex:0 animated:YES];_selectSegment.segmentedControlStyle = UISegmentedControlStyleBar;[_selectSegment addTarget:self action:@selector(selectSegmentAction:)forControlEvents:UIControlEventValueChanged]; [self.navigationController.navigationBar addSubview:_selectSegment];[_selectSegment release];_selectSegment.selectedSegmentIndex = -1;
这一段就是创建一个segment的控件,然后加在NavigationBar上面,将它的UIControlEventValueChanged事件绑定到selectSegmentAction:上面。So,我们点击这个segment后,就会触发selectSegmentAction:,其原型,后面就会贴出来,告诉你它干了什么见不得人的事儿。
2.创建一个UITableView作为下拉框:
[c-sharp] view plain copy print ?
- /*
- @property (nonatomic, retain) NSArray *comboBoxDatasource;
- @synthesize comboBoxDatasource ;
- */
- _comboBoxTableView = [[UITableView alloc] initWithFrame:CGRectMake(x,y,length,height) style:UITableViewStylePlain];
- _comboBoxTableView.dataSource = self;
- _comboBoxTableView.delegate = self;
- _comboBoxTableView.backgroundColor = [UIColor clearColor];
- _comboBoxTableView.separatorColor = [UIColor clearColor];
- _comboBoxTableView.hidden = YES;
- [self.view addSubview:_comboBoxTableView];
- [_comboBoxTableView release];
- self.comboBoxDatasource = [[NSArray alloc] initWithObjects:@"1th", @"2th", @"3th",nil];
/*@property (nonatomic, retain) NSArray *comboBoxDatasource;@synthesize comboBoxDatasource ;*/_comboBoxTableView = [[UITableView alloc] initWithFrame:CGRectMake(x,y,length,height) style:UITableViewStylePlain];_comboBoxTableView.dataSource = self;_comboBoxTableView.delegate = self;_comboBoxTableView.backgroundColor = [UIColor clearColor];_comboBoxTableView.separatorColor = [UIColor clearColor];_comboBoxTableView.hidden = YES;[self.view addSubview:_comboBoxTableView];[_comboBoxTableView release]; self.comboBoxDatasource = [[NSArray alloc] initWithObjects:@"1th", @"2th", @"3th",nil];
这里呢就是创建一个UITableView加在self.view上面,当然你可以加在window这个电视上面:
[c-sharp] view plain copy print ?
- UIWindow* window=[[UIApplication sharedApplication] keyWindow];
- [window addSubview:_comboBoxTableView];
UIWindow* window=[[UIApplication sharedApplication] keyWindow]; [window addSubview:_comboBoxTableView];
一般情况下呢,还需要为其添加一个背景色(图片),否则,下拉的效果将像凤姐一样让人生畏。
[c-sharp] view plain copy print ?
- _tableViewImageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,length,height)];
- [_tableViewImageView setImage:[UIImage imageNamed:@"comboxBackGround.png"]];
- [self.view addSubview:_tableViewImageView];
- [_tableViewImageView release];
- [_tableViewImageView setHidden:YES];
_tableViewImageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,length,height)]; [_tableViewImageView setImage:[UIImage imageNamed:@"comboxBackGround.png"]]; [self.view addSubview:_tableViewImageView]; [_tableViewImageView release];[_tableViewImageView setHidden:YES];
位置当然需要慢慢调整,图层当然是放在tableview 的下面了,YY一下了,免得有的新手出不来又要哭半天。
3.tableView的数据
这个我感觉都没啥必要讲了,不过考虑到新手还是贴一段吧!
[c-sharp] view plain copy print ?
- #pragma mark -
- #pragma mark UITableViewDelegate and UITableViewDatasource methods
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return [comboBoxDatasource count];
- }
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
- return 1;
- }
- - (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section
- {
- return nil;
- }
- - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
- {
- UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f,0.0f, 120.0f,20.0f)]autorelease];
- label.backgroundColor = [UIColor clearColor];
- label.text = @"Picture setting";
- label.textColor = [UIColor grayColor];
- label.font = [UIFont systemFontOfSize:10];
- label.textAlignment = UITextAlignmentCenter;
- return label;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellIdentifier = @"CellIdentifier";
- UITableViewCell *cell = [_comboBoxTableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
- }
- cell.textLabel.text = (NSString *)[comboBoxDatasource objectAtIndex:indexPath.row];
- cell.textLabel.font = [UIFont systemFontOfSize:12.0f];
- cell.textLabel.textColor = [UIColor whiteColor];
- [cell setAlpha:1.0f];
- if(indexPath.section == 0){
- if(indexPath.row == 0){
-
- }else if(indexPath.row == 1){
-
- }else if(indexPath.row == 2){
-
- }
- }
- cell.accessoryType = UITableViewCellAccessoryNone;
- cell.selectionStyle = UITableViewCellSelectionStyleBlue;
- return cell;
- }
-
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
- return 20.0f;
- }
-
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- [self hidden];
- [self selectedAction:indexPath.row];
- [comboBoxTableView reloadData];
- }
#pragma mark -#pragma mark UITableViewDelegate and UITableViewDatasource methods- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [comboBoxDatasource count];}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1;}- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section { return nil;} - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f,0.0f, 120.0f,20.0f)]autorelease]; label.backgroundColor = [UIColor clearColor]; label.text = @"Picture setting"; label.textColor = [UIColor grayColor]; label.font = [UIFont systemFontOfSize:10]; label.textAlignment = UITextAlignmentCenter; return label;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [_comboBoxTableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } cell.textLabel.text = (NSString *)[comboBoxDatasource objectAtIndex:indexPath.row]; cell.textLabel.font = [UIFont systemFontOfSize:12.0f]; cell.textLabel.textColor = [UIColor whiteColor]; [cell setAlpha:1.0f]; if(indexPath.section == 0){ if(indexPath.row == 0){ }else if(indexPath.row == 1){ }else if(indexPath.row == 2){ } } cell.accessoryType = UITableViewCellAccessoryNone; cell.selectionStyle = UITableViewCellSelectionStyleBlue; return cell;} - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 20.0f;} - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self hidden]; [self selectedAction:indexPath.row]; [comboBoxTableView reloadData];}
4.tableView的动作:
[c-sharp] view plain copy print ?
- #pragma mark -
- #pragma mark combox action methods
-
- //If a row selected ,this function will go.
- - (void)selectedAction:(int)index {
- switch (index) {
- case 0:
- break;
- case 1:
- break;
- case 2:
- break;
-
- default:
- break;
- }
- }
-
- //comboBox show ,and _showComboBox is it's flag that means current status
- - (void)comboBoxShow {
- _comboBoxTableView.hidden = NO;
- _showComboBox = YES;
- [_tableViewImageView setHidden:NO];
- }
-
- //hidden comboBox whenever if this function called.
- - (void)comboBoxHidden {
- _comboBoxTableView.hidden = YES;
- _showComboBox = NO;
- [_tableViewImageView setHidden:YES];
- }
#pragma mark -#pragma mark combox action methods //If a row selected ,this function will go.- (void)selectedAction:(int)index { switch (index) { case 0: break; case 1: break; case 2: break; default: break; }} //comboBox show ,and _showComboBox is it's flag that means current status- (void)comboBoxShow { _comboBoxTableView.hidden = NO; _showComboBox = YES; [_tableViewImageView setHidden:NO];} //hidden comboBox whenever if this function called.- (void)comboBoxHidden { _comboBoxTableView.hidden = YES; _showComboBox = NO; [_tableViewImageView setHidden:YES];}
5.All right,最后我们添加一个事件,在点击屏幕其它地方的时候就把空上下拉框给Hiden起来。以上我们的控件都是加在UIView上面的,我们需要把uiview改成UIControl 。这样子就可以响应事件了。
[contentView addTarget:self action:@selector(backgroundTap:) forControlEvents:UIControlEventTouchDown];
在backgroundTap里面就直接调用comboBoxHidden 就OK了。
至此,基于的下拉菜单就大功告成了,至于其它优化什么的,就慢慢去琢磨吧!