tableView下拉框的实现

因为需求原因, 所以这里表述的是点击按钮打开和关闭下拉框, 如果需要TF文本输入框输入可以自行修改.
下面就代码个实现一起写吧, 先说下大概的思路. 将tableView和button封装在一个视图里, 就是所谓的下拉框. 点击button的时候传入数据, 刷新tableView的数据源, 根据数据源可自己处理tableView相应的展示高度, 根据tableView的高度设置总体的View的高度. 这样就可达到下拉框的效果了.
【tableView下拉框的实现】首先自定义一个View继承自UIView:

#import //下面这两个是获取的屏幕宽和高, 一般都放入pch文件 #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height @class JGKDropView; @protocol JGKDropViewDelegate //代理, 用于处理选择下拉框下选项的操作 -(void)selectAtIndex:(int)index WithJGKDrop:(JGKDropView *)KunView; @end@interface JGKDropView : UIView@property(nonatomic, strong)UIButton *button; //显示的button(点击可以展开和收起下拉框) @property(nonatomic, strong)UITableView *tableview; //下拉框要显示的内容 @property(nonatomic, assign)CGFloat buttonWidth; //自定义设置, 需要用到. 各位个根据需要添加//数据部分 @property(nonatomic,strong)NSMutableArray *arr; //tableView的数据源 @property(nonatomic,assign)BOOL buttonImageFlag; //判断表格是否打开或者关闭 @property(nonatomic,assign)iddelegate; //设置的View的调用方法(类似于初始化的使用) - (void)setViewOriginx:(int)originx ViewOriginy:(int)originy buttonHeight:(int)buttonHeight buttonWeight:(int)buttonWeight tableViewHeight:(int)tableViewHeigh; //刷新数据源 - (void)reloadataTableview; //关闭tableView - (void)closeTableview; @end

接下来是.m的实现
#import "JGKDropView.h" #import "JGKDropCell.h" //自己定义的cell, 待会儿会粘贴在下面, 也可以直接写在tableView的代理方法里面, 看个人习惯#define kBorderColor[UIColor colorWithRed:219/255.0 green:217/255.0 blue:216/255.0 alpha:1]@implementation JGKDropView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; self.button = [UIButton buttonWithType:UIButtonTypeCustom]; [self addSubview:_button]; } return self; }//一共五个参数, 分别代表该View的x, y, button的高度和宽度四个值. 最后一个代表tableView的高度 - (void)setViewOriginx:(int)originx ViewOriginy:(int)originy buttonHeight:(int)buttonHeight buttonWeight:(int)buttonWeight tableViewHeight:(int)tableViewHeight{ //注册自己的cell [self.tableview registerClass:[JGKDropCell class] forCellReuseIdentifier:@"cell"]; self.layer.borderColor = kBorderColor.CGColor; self.layer.borderWidth = 1; //button的高度给了 self.buttonWidth = buttonWeight; self.frame = CGRectMake(originx, originy, buttonWeight, buttonHeight + tableViewHeight); _buttonImageFlag = YES; //button的宽度以及tableView的宽度都和View的一样 _button.frame = CGRectMake(0,0,self.bounds.size.width , buttonHeight); //[_button setBackgroundImage:[UIImage imageNamed:@"down_dark0"] forState:UIControlStateNormal]; [_button addTarget:self action:@selector(tableShowAndHide:) forControlEvents:UIControlEventTouchUpInside]; [_button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //处理tableView self.tableview.frame = CGRectMake(0,buttonHeight,self.bounds.size.width, 0); } //tableView的懒加载 - (UITableView *)tableview { if (!_tableview) { self.tableview = [[UITableView alloc]initWithFrame:CGRectMake(0,0,self.bounds.size.width, 0) style:UITableViewStylePlain]; _tableview.backgroundColor= [UIColor colorWithWhite:1 alpha:0.6]; //_tableview.layer.cornerRadius = 3; _tableview.separatorStyle =UITableViewCellSeparatorStyleNone; _tableview.hidden = YES; _tableview.delegate =self; _tableview.dataSource = self; //_tableview.layer.borderWidth= 0.3; [self addSubview:_tableview]; } return _tableview; } //按钮的触发事件, 触发是否展示下拉框 -(void)tableShowAndHide:(UIButton *)btn { //如果button设置为yes if (_buttonImageFlag==YES) {//刷新数据 [self reloadataTableview]; //由外部传进来的数据源数组的数量决定tableView的高度, 想怎么处理自己可以处理. 我这里是超过4条数据就让它自己滑动就可以了, 不做过多展示.假定每个cell的高度为23 if (_arr.count < 4) { self.tableview.frame = CGRectMake(0,_button.frame.size.height,self.bounds.size.width, _arr.count * 23); } else { self.tableview.alwaysBounceVertical = YES; self.tableview.frame = CGRectMake(0,_button.frame.size.height,self.bounds.size.width, 69); } [self.tableview flashScrollIndicators]; //以下几行代码修改View的frame的值 CGRect rect = self.frame; rect.size.height = _button.frame.size.height + _tableview.frame.size.height; self.frame = rect; //_buttonImageFlag设置为NO, 处理下次点击的触发事件 _buttonImageFlag = NO; _tableview.hidden = NO; } else {//为NO就关闭列表[self closeTableview]; } } //刷新表格 -(void)reloadataTableview { [self.tableview reloadData]; } //关闭表格 -(void)closeTableview { //同上的打开表格一样(处理事件) _buttonImageFlag = YES; CGRect rect = self.frame; rect.size.height = _button.frame.size.height; self.frame = rect; _tableview.hidden = YES; }以下就是tableView的代理 #pragma mark tabelview delegate -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return _arr.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdenttifier = @"cell"; JGKDropCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdenttifier]; if (cell==nil) { cell = [[JGKDropCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdenttifier]; } [cell configureWithStr:_arr[indexPath.row] boundsWidth:_buttonWidth]; return cell; } //-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section //{ //UIView *view = [[UIView alloc]initWithFrame:CGRectMake(tableView.frame.origin.x, 0, tableView.frame.size.width, 0)]; //return view; //} -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //个人原因, 才-2, 可自行测试使用 return _button.bounds.size.height - 2; }-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //将数组中的字体赋值给框 [_button setTitle:_arr[indexPath.row] forState:UIControlStateNormal]; //选中之后关闭输入框 [self closeTableview]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; //走代理方法 if ([_delegate respondsToSelector:@selector(selectAtIndex:WithJGKDrop:)]) { //如果代理方法实现, 则走自己的代理 [_delegate selectAtIndex:(int)indexPath.row WithJGKDrop:self]; } }@end

然后把cell的代码粘贴上:
@interface JGKDropCell : UITableViewCell@property (strong, nonatomic) UILabel *showCarLabel; @property (strong, nonatomic) UILabel *lineLabel; - (void)configureWithStr:(NSString *)Str boundsWidth:(CGFloat)width; @end接下来是.m的 @implementation JGKDropCell- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.backgroundColor = [UIColor clearColor]; [self.contentView addSubview:self.showCarLabel]; } return self; }- (UILabel *)showCarLabel { if (!_showCarLabel) { self.showCarLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, (kScreenWidth/ 2) - 65 , 23)]; //字体可以根据宽度和高度动态给, 便于方便就直接给了 self.showCarLabel.font = [UIFont systemFontOfSize:14]; //self.showCarLabel.text = _arr[indexPath.row]; self.showCarLabel.textAlignment = NSTextAlignmentCenter; self.lineLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 22, (kScreenWidth/ 2) - 65 , 0.5)]; self.lineLabel.backgroundColor = [UIColor blackColor]; [self.showCarLabel addSubview:_lineLabel]; } return _showCarLabel; }- (void)configureWithStr:(NSString *)Str boundsWidth:(CGFloat)width{ self.showCarLabel.text = Str; self.showCarLabel.frame = CGRectMake(0, 0, width , 23); self.lineLabel.frame = CGRectMake(0, 22, width , 0.5); }- (void)awakeFromNib { // Initialization code }- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state }@end

用的时候在需要的控制器或者视图里面加上就可以了.
我是这样用的, 当时比较新手, 写的比较累赘, 用着也不方便给大家贴以下当时的代码:
//这是懒加载 - (JGKDropView *)jgkDropView { if (!_jgkDropView) { self.jgkDropView = [[JGKDropView alloc] init]; [self.jgkDropView setViewOriginx:55 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 65tableViewHeight:0]; [self.carFlag closeTableview]; } return _jgkDropView; }//这是全局的方法, 传入arr然后刷新数据源 - (void)configureChooseNewJGKView:(NSMutableArray *)arr { self.jgkDropView.arr = arr; self.jgkDropView.tag = 2000; //[self.jgkDropView reloadataTableview]; //这里也可以不刷新, 因为点击按钮会自动刷新 if (arr.count == 1) { [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75tableViewHeight:23]; } else if (arr.count == 2) { [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75tableViewHeight:46]; } else if (arr.count == 3) { [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75tableViewHeight:69]; } else { [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75tableViewHeight:0]; } [self.jgkDropView closeTableview];

整体是思路就是这样, 代码是按照以前写的贴的, 可以大大的简化, 这里不写了 给个思路吧, 就是主要是根据传进去的数组, 去改变整体View的高度, button的高度不会变, 也就是改变tableView的高度. 所以外部拼接的方法就是一个数组就可以了, 不需要像我这样这么多参数每次都要调用一样麻烦, 新手看完应该就可以理解并修改. 大神略过

    推荐阅读