tableView下拉框的实现

因为需求原因, 所以这里表述的是点击按钮打开和关闭下拉框, 如果需要TF文本输入框输入可以自行修改.

下面就代码个实现一起写吧, 先说下大概的思路. 将tableView和button封装在一个视图里, 就是所谓的下拉框. 点击button的时候传入数据, 刷新tableView的数据源, 根据数据源可自己处理tableView相应的展示高度, 根据tableView的高度设置总体的View的高度. 这样就可达到下拉框的效果了.

首先自定义一个View继承自UIView:

#import 
//下面这两个是获取的屏幕宽和高, 一般都放入pch文件
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
@class JGKDropView; 
@protocol JGKDropViewDelegate <NSObject>
//代理, 用于处理选择下拉框下选项的操作
-(void)selectAtIndex:(int)index WithJGKDrop:(JGKDropView *)KunView;

@end

@interface JGKDropView : UIView<UITableViewDelegate, UITableViewDataSource>

@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) - 65  tableViewHeight: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) - 75  tableViewHeight:23];
    } else if (arr.count == 2) {
        [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75  tableViewHeight:46];
    } else if (arr.count == 3) {
        [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75  tableViewHeight:69];
    } else {
        [self.jgkDropView setViewOriginx:70 ViewOriginy:10 buttonHeight:23 buttonWeight:(kScreenWidth/ 2) - 75  tableViewHeight:0];
    }
    [self.jgkDropView closeTableview];

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

你可能感兴趣的:(tableView下拉框的实现)