因为需求原因, 所以这里表述的是点击按钮打开和关闭下拉框, 如果需要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的高度. 所以外部拼接的方法就是一个数组就可以了, 不需要像我这样这么多参数每次都要调用一样麻烦, 新手看完应该就可以理解并修改. 大神略过