@class DropDownView; #define SECTION_BTN_TAG_BEGIN 1000 #define SECTION_IV_TAG_BEGIN 3000 @protocol DropDownViewDelegate <NSObject> @optional /** * 点击触发事件 * @param indexPath 被点击的分区及行 */ - (void)dropDownView:(DropDownView *)dropDownView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; @end @protocol DropDownViewDataSource <NSObject> @required /** * 当前分区中的行数 * @param section 分区 * * @return 行数 */ - (NSInteger)dropDownView:(DropDownView *)dropDownView numberOfRowsInSection:(NSInteger)section; /** * 当前分区的每行的标题 * @param indexPath 分区 * * @return 每行的标题 */ - (NSString *)dropDownView:(DropDownView *)dropDownView titleForRowAtIndexPath:(NSIndexPath *)indexPath; /** * 默认选中的行 * * @param row 行数 * * @return 默认选中的行数 */ - (NSInteger)defaultShowRow:(NSInteger)row; @optional /** * 分区数 * * @return 分区数 */ - (NSInteger)numberOfSectionsInDropDownView:(DropDownView *)dropDownView; @end @interface DropDownView : UIView <UITableViewDelegate,UITableViewDataSource> /** * 数据源代理 */ @property (nonatomic, assign) id <DropDownViewDataSource> dataSource; /** * 代理 */ @property (nonatomic, assign) id <DropDownViewDelegate> delegate; /** * 分组的宽度 */ @property (nonatomic, assign) CGFloat sectionWidth; /** * 父视图 */ @property (nonatomic, strong) UIView *mySuperView; /** * 初始化方法 * * @param frame 坐标 * @param delegate 代理 * @param dataSource 数据源代理 * * @return dropView */ - (instancetype)initWithFrame:(CGRect)frame delegate:(id)delegate dataSource:(id)dataSource;
#define DEGREES_TO_RADIANS(angle) ((angle)/180.0 *M_PI) #define RADIANS_TO_DEGREES(radians) ((radians)*(180.0/M_PI)) @interface DropDownView () { /**当前展开的section,默认-1,表示没有展开*/ NSInteger currentExtendSection; /**当前分数个数*/ NSInteger sectionNum; } /** * 根视图 */ @property (nonatomic, strong) UIView *myBasicView; /** * 显示数据的dropview */ @property (nonatomic, strong) UITableView *myTableView; /** * 设置每个分区的标题 * * @param title 标题 * @param section 分区 */ - (void)setTitle:(NSString *)title inSection:(NSInteger)section; /** * 是否隐藏 */ - (void)hideExtendedChooseView; @end @implementation DropDownView - (instancetype)initWithFrame:(CGRect)frame delegate:(id)delegate dataSource:(id)dataSource { if (self = [super initWithFrame:frame]) { //对参数初始化 self.backgroundColor = [UIColor whiteColor]; currentExtendSection = -1; sectionNum = 0; self.delegate = delegate; self.dataSource = dataSource; //返回分区个数 if ([self.dataSource respondsToSelector:@selector(numberOfSectionsInDropDownView:)]) { sectionNum = [self.dataSource numberOfSectionsInDropDownView:self]; } if (sectionNum == 0) { self = nil; } //初始化默认显示的view CGFloat sectionWidth = _sectionWidth == 0 ? (1.0*(frame.size.width)/sectionNum) : _sectionWidth; for (NSInteger i = 0; i < sectionNum; i++) { UIButton *sectionBtn = [[UIButton alloc] initWithFrame:CGRectMake(sectionWidth*i, 1, sectionWidth, frame.size.height-2)]; sectionBtn.tag = SECTION_BTN_TAG_BEGIN + i; [sectionBtn addTarget:self action:@selector(sectionBtnTouch:) forControlEvents:UIControlEventTouchUpInside]; NSString *sectionBtnTitle = @""; if ([self.dataSource respondsToSelector:@selector(dropDownView:titleForRowAtIndexPath:)]) { //取出对应分区对应行的标题 sectionBtnTitle = [self.dataSource dropDownView:self titleForRowAtIndexPath:[NSIndexPath indexPathForRow:[self.dataSource defaultShowRow:i] inSection:i]]; } [sectionBtn setTitle:sectionBtnTitle forState:UIControlStateNormal]; [sectionBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; sectionBtn.titleLabel.font = [UIFont boldSystemFontOfSize:14.0]; [self addSubview:sectionBtn]; //箭头 UIImageView *sectionBtnIv = [[UIImageView alloc] initWithFrame:CGRectMake(sectionWidth*i +(sectionWidth - 16), (self.frame.size.height-12)/2, 12, 12)]; [sectionBtnIv setImage:[UIImage imageNamed:@"down_dark.png"]]; [sectionBtnIv setContentMode:UIViewContentModeScaleToFill]; sectionBtnIv.tag = SECTION_IV_TAG_BEGIN + i; [self addSubview: sectionBtnIv]; //分隔线 if (i<sectionNum && i != 0) { UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(sectionWidth*i, frame.size.height/4, 1, frame.size.height/2)]; lineView.backgroundColor = [UIColor blueColor]; [self addSubview:lineView]; } } } return self; } #pragma mark - 分区被点击 - (void)sectionBtnTouch:(UIButton *)btn { NSInteger section = btn.tag - SECTION_BTN_TAG_BEGIN; UIImageView *currentIV= (UIImageView *)[self viewWithTag:(SECTION_IV_TAG_BEGIN +currentExtendSection)]; [UIView animateWithDuration:0.3 animations:^{ currentIV.transform = CGAffineTransformRotate(currentIV.transform, DEGREES_TO_RADIANS(180)); }]; if (currentExtendSection == section) { [self hideExtendedChooseView]; }else{ currentExtendSection = section; currentIV = (UIImageView *)[self viewWithTag:SECTION_IV_TAG_BEGIN + currentExtendSection]; [UIView animateWithDuration:0.3 animations:^{ currentIV.transform = CGAffineTransformRotate(currentIV.transform, DEGREES_TO_RADIANS(180)); }]; [self showChooseListViewInSection:currentExtendSection choosedIndex:[self.dataSource defaultShowRow:currentExtendSection]]; } } - (void)setTitle:(NSString *)title inSection:(NSInteger) section { UIButton *btn = (id)[self viewWithTag:SECTION_BTN_TAG_BEGIN +section]; [btn setTitle:title forState:UIControlStateNormal]; } - (void)hideExtendedChooseView { if (currentExtendSection != -1) { currentExtendSection = -1; CGRect rect = self.myTableView.frame; rect.size.height = 0; [UIView animateWithDuration:0.3 animations:^{ self.myBasicView.alpha = 1.0f; self.myTableView.alpha = 1.0f; self.myBasicView.alpha = 0.2f; self.myTableView.alpha = 0.2; self.myTableView.frame = rect; }completion:^(BOOL finished) { [self.myTableView removeFromSuperview]; [self.myBasicView removeFromSuperview]; }]; } } -(void)showChooseListViewInSection:(NSInteger)section choosedIndex:(NSInteger)index { if (!self.myTableView) { self.myBasicView = [[UIView alloc] initWithFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height , self.frame.size.width, self.mySuperView.frame.size.height - self.frame.origin.y - self.frame.size.height)]; self.myBasicView.backgroundColor = [UIColor yellowColor]; UITapGestureRecognizer *bgTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(bgTappedAction:)]; [self.myBasicView addGestureRecognizer:bgTap]; self.myTableView = [[UITableView alloc] initWithFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height, self.frame.size.width, 100) style:UITableViewStylePlain]; self.myTableView.backgroundColor = [UIColor redColor]; self.myTableView.delegate = self; self.myTableView.dataSource = self; self.myTableView.separatorStyle = UITableViewCellSeparatorStyleNone; } //修改tableview的frame int sectionWidth = (self.frame.size.width)/[self.dataSource numberOfSectionsInDropDownView:self]; CGRect rect = self.myTableView.frame; rect.origin.x = sectionWidth *section; rect.size.width = sectionWidth; rect.size.height = 0; self.myTableView.frame = rect; [self.mySuperView addSubview:self.myBasicView]; [self.mySuperView addSubview:self.myTableView]; //动画设置位置 NSLog(@"%li",[self.dataSource numberOfSectionsInDropDownView:self]); rect.size.height = ([self.dataSource dropDownView:self numberOfRowsInSection:currentExtendSection])* 40 + 10; [UIView animateWithDuration:0.3 animations:^{ self.myBasicView.alpha = 0.2; self.myTableView.alpha = 0.2; self.myBasicView.alpha = 1.0; self.myTableView.alpha = 1.0; self.myTableView.frame = rect; }]; [self.myTableView reloadData]; } -(void)bgTappedAction:(UITapGestureRecognizer *)tap { UIImageView *currentIV = (UIImageView *)[self viewWithTag:(SECTION_IV_TAG_BEGIN + currentExtendSection)]; [UIView animateWithDuration:0.3 animations:^{ currentIV.transform = CGAffineTransformRotate(currentIV.transform, DEGREES_TO_RADIANS(180)); }]; [self hideExtendedChooseView]; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([self.delegate respondsToSelector:@selector(dropDownView:didSelectRowAtIndexPath:)]) { NSString *chooseCellTitle = [self.dataSource dropDownView:self titleForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:currentExtendSection]]; UIButton *currentSectionBtn = (UIButton *)[self viewWithTag:SECTION_BTN_TAG_BEGIN + currentExtendSection]; [currentSectionBtn setTitle:chooseCellTitle forState:UIControlStateNormal]; [self.delegate dropDownView:self didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:currentExtendSection]]; [self hideExtendedChooseView]; } } #pragma mark - UITableView DataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.dataSource dropDownView:self numberOfRowsInSection:currentExtendSection]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * cellIdentifier = @"cellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; cell.accessoryType = UITableViewCellAccessoryNone; } cell.textLabel.text = [self.dataSource dropDownView:self titleForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:currentExtendSection]]; cell.textLabel.font = [UIFont systemFontOfSize:14]; return cell; }
@interface ViewController () <DropDownViewDataSource,DropDownViewDelegate> { NSMutableArray *chooseArray; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. chooseArray = [NSMutableArray arrayWithArray:@[ @[@"童明城1",@"童赟2",@"童林杰3",@"老萧狗4"], @[@"童明城1",@"童赟2",@"童林杰3",@"老萧狗4"], @[@"童明城1",@"童赟2",@"童林杰3",@"老萧狗4",@"童明城1",@"童赟2",@"童林杰3",@"老萧狗4",@"童明城1",@"童赟2",@"童林杰3",@"老萧狗4"] ]]; DropDownView * dropDownView = [[DropDownView alloc] initWithFrame:CGRectMake(0, 64, 300, 40) delegate:self dataSource:self]; dropDownView.backgroundColor = [UIColor lightGrayColor]; dropDownView.mySuperView = self.view; self.view.backgroundColor = [UIColor magentaColor]; [self.view addSubview:dropDownView]; } - (void)dropDownView:(DropDownView *)dropDownView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"%li %li",indexPath.section,indexPath.row); } - (NSInteger)numberOfSectionsInDropDownView:(DropDownView *)dropDownView { return chooseArray.count; } - (NSInteger)dropDownView:(DropDownView *)dropDownView numberOfRowsInSection:(NSInteger)section { return [chooseArray[section] count]; } - (NSString *)dropDownView:(DropDownView *)dropDownView titleForRowAtIndexPath:(NSIndexPath *)indexPath { return chooseArray[indexPath.section][indexPath.row]; } - (NSInteger)defaultShowRow:(NSInteger)row { return 0; }
主要思想:类比UITableView封装了一个DropDownView
继承于UIView遵守UITableViewDelegate和UITableViewDataSource封装的。
由section组和row行组成。
首先就是要把所有的数据显示在TableViewCell里面,如果currentExtendSection!=-1那么就是展开的,否则就是关闭的。
隐藏的时候最好把TableView以及BasciView清空,不然可能会导致内存泄露。