最近自由时间有点多,就开始撸控件。这个是我们常用的一个下拉分类控件,看了很多别人写的,都是用TableView或者CollectionView整合在一起的感觉自定义性没有那么强,所以就尝试用把TableView和CollectionView替换成UIViewController。其他废话不多说了。

1、 接口文件

#import <UIKit/UIKit.h>UIKIT_EXTERN NSString *lzDropViewNotification;NS_ASSUME_NONNULL_BEGIN@class LZDropView;
@protocol LZDropViewDataSource <NSObject>@required/** Height corresponding to controller display */
- (NSArray<NSNumber *> *)setupCategoryControllerHeightInDropView:(LZDropView *)dropView;
/** Title corresponding controller array */
- (NSArray<UIViewController *> *)setupCategoryControllerInDropView:(LZDropView *)dropView;
/** Default display of Title Array */
- (NSArray<NSString *> *)setupCategoryTitleNameInDropView:(LZDropView *)dropView;@end@protocol LZDropViewDelegate <NSObject>/** Click the column and select the information. */
- (void)dropView:(LZDropView *)dropView didSelectAtColumn:(NSInteger)column info:(NSString *)info;@end@interface LZDropView : UIView
/** Simple page configuration */
@property (nonatomic, weak) id <LZDropViewDataSource> dataSorce;
/** Click proxy event<##> */
@property (nonatomic, weak) id <LZDropViewDelegate> delegate;@endNS_ASSUME_NONNULL_END
复制代码

2、 实现文件

#import "LZDropView.h"NSString *lzDropViewNotification = @"nitification";@interface LZDropView ()@property (nonatomic, strong) NSArray<UIViewController *> *controllerArray;
@property (nonatomic, strong) NSArray<NSString *> *titleArray;
@property (nonatomic, strong) UIButton *containerView;
@property (nonatomic, strong) NSArray<NSNumber *> *controllerHeightArray;
@property (nonatomic, strong) NSMutableArray<UIButton *> *buttonArray;@end@implementation LZDropView#pragma mark - Release memory- (void)dealloc {[[NSNotificationCenter defaultCenter] removeObserver:self];
}#pragma mark - Initialization- (instancetype)init {self = [super init];if (self) {[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationAction:) name:lzDropViewNotification object:nil];}return self;
}#pragma mark - Draw the page- (void)setupTitleButton:(NSArray<NSString *> *)array {CGFloat width = UIScreen.mainScreen.bounds.size.width / array.count;self.buttonArray = [NSMutableArray array];for (NSString *name in array) {NSInteger index = [array indexOfObject:name];UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];button.titleLabel.font = [UIFont systemFontOfSize:15];[button setTitle:[NSString stringWithFormat:@"%@ ▼", name] forState:UIControlStateNormal];[button setTitle:[NSString stringWithFormat:@"%@ ▲", name] forState:UIControlStateSelected];[button setTitleColor:UIColor.grayColor forState:UIControlStateNormal];[button setTitleColor:UIColor.orangeColor forState:UIControlStateSelected];button.frame = CGRectMake(width * index, 0, width, 45);button.tag = index + 1000;[button addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];[self addSubview:button];[self.buttonArray addObject:button];}
}#pragma mark - Button click event- (void)buttonTouched:(UIButton *)sender {if (sender.selected) {[self closeControllerView];} else {[self openControllerViewWithButton:sender];}
}- (void)backButtonTouched:(UIButton *)sender {[self closeControllerView];
}#pragma mark - Notification event- (void)notificationAction:(NSNotification *)notification {    if (![self.controllerArray containsObject:notification.object]) {return;}NSInteger index = [self.controllerArray indexOfObject:notification.object];UIButton *button = self.buttonArray[index];[button setTitle:[NSString stringWithFormat:@"%@ ▼", notification.userInfo.allValues.firstObject] forState:UIControlStateNormal];if (self.delegate && [self.delegate respondsToSelector:@selector(dropView:didSelectAtColumn:info:)]) {[self.delegate dropView:self didSelectAtColumn:index info:notification.userInfo.allValues.firstObject];}[self closeControllerView];
}#pragma mark - Close all controllers.- (void)closeControllerView {[UIView animateWithDuration:0.8 animations:^{self.containerView.alpha = 0;self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), UIScreen.mainScreen.bounds.size.width, 0);} completion:^(BOOL finished) {[self.containerView removeFromSuperview];}];for (UIButton *button in self.buttonArray) {button.selected = false;}
}#pragma mark - Open the corresponding controller.- (void)openControllerViewWithButton:(UIButton *)sender {for (UIButton *button in self.buttonArray) {button.selected = false;}self.containerView.alpha = 1;for (UIView *view in self.containerView.subviews) {[view removeFromSuperview];}UIViewController *vc = self.controllerArray[sender.tag - 1000];double vcHeight = [self.controllerHeightArray[sender.tag - 1000] doubleValue];self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), self.frame.size.width, 0);vc.view.frame = CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, 0);[self.superview addSubview:self.containerView];[self.containerView addSubview:vc.view];[UIView animateWithDuration:0.6 animations:^{self.containerView.frame = CGRectMake(0, CGRectGetMaxY(self.frame), self.frame.size.width, UIScreen.mainScreen.bounds.size.height);vc.view.frame = CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, vcHeight);} completion:^(BOOL finished) {}];sender.selected = true;
}#pragma mark - Getter- (UIView *)containerView {if (!_containerView) {_containerView = [[UIButton alloc] init];_containerView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1];[_containerView addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside];}return _containerView;
}#pragma mark - Setter- (void)setDataSorce:(id<LZDropViewDataSource>)dataSorce {_dataSorce = dataSorce;if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryControllerInDropView:)]){self.controllerArray = [self.dataSorce setupCategoryControllerInDropView:self];}if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryTitleNameInDropView:)]){self.titleArray = [self.dataSorce setupCategoryTitleNameInDropView:self];[self setupTitleButton:self.titleArray];}if (self.dataSorce && [self.dataSorce respondsToSelector:@selector(setupCategoryControllerHeightInDropView:)]) {self.controllerHeightArray = [self.dataSorce setupCategoryControllerHeightInDropView:self];}if (self.controllerArray.count != self.titleArray.count ||self.controllerArray.count != self.controllerHeightArray.count) {@throw [NSException exceptionWithName:NSStringFromClass([self class]) reason:@"The number of corresponding arrays is inconsistent." userInfo:nil];}
}@end
复制代码

使用方式

1.遵循协议

<LZDropViewDataSource, LZDropViewDelegate>
复制代码

2.初始化

LZDropView *view     = [[LZDropView alloc] init];view.dataSorce       = self;view.delegate        = self;view.backgroundColor = UIColor.whiteColor;view.frame           = CGRectMake(0, 100, UIScreen.mainScreen.bounds.size.width, 45);[self.view addSubview:view];
复制代码
  1. 实现代理和数据源
#pragma mark - LZDropViewDataSource- (NSArray<UIViewController *> *)setupCategoryControllerInDropView:(LZDropView *)dropView {return @[[[TableViewController alloc] init],[[TableViewController alloc] init],[[TableViewController alloc] init],[[TableViewController alloc] init]];
}- (NSArray<NSString *> *)setupCategoryTitleNameInDropView:(LZDropView *)dropView {return @[@"全部",@"附近",@"只能排序",@"筛选"];
}- (NSArray<NSNumber *> *)setupCategoryControllerHeightInDropView:(LZDropView *)dropView {return @[[NSNumber numberWithFloat:300],[NSNumber numberWithFloat:400],[NSNumber numberWithFloat:410],[NSNumber numberWithFloat:420]];
}#pragma mark - LZDropViewDelegate- (void)dropView:(LZDropView *)dropView didSelectAtColumn:(NSInteger)column info:(NSString *)info {NSLog(@"%ld---%@", column, info);
}复制代码
  1. 点击controller中的数据显示在按钮的标题中,这因为跨界面显示,我暂时没有想到好的办法,所以使用强大的通知传值。
  2. 记录选中状态,应该是控制器里面的操作,这里就没有实现
[[NSNotificationCenter defaultCenter] postNotificationName:lzDropViewNotification object:self userInfo:@{@"key":[NSString stringWithFormat:@"第%ldcell", indexPath.row]}];
复制代码

如果有什么不好如果建议的地方,请批评指正!

iOS自定义控件:简易下拉控件相关推荐

  1. 具有TreeView下拉控件的ComboBox

    具有TreeView下拉控件的ComboBox 没错,如标题所说的那样,在下拉框中是一个TreeView,但是,为什么我们需要这样的控件?事实上这样的需求我已经遇到很多次了,比如适用于:  当遇到层 ...

  2. 自定义可扩展叠加头部的下拉控件

    最近写了个下拉控件,和几个下拉的头部样式,下拉控件可以连续添加叠加几个头部视图 下面是没有添加任何头部尾部的视图下拉效果 一步一步来介绍,先介绍这个下拉效果,在介绍自定义的头部 首先在使用上,和普通的 ...

  3. html下拉框 multiple,多选下拉控件的使用(select-option)multiple-select

    多选下拉控件的使用(select-option) 1.第一个组件是写bootstrap table的主人公 2.第二个组件 本篇中使用的是第一个控件来实现多选下拉框: 首先引入支持文件 multipl ...

  4. Unity 之 UGUI Dropdown下拉控件展开方向控制

    Unity 之 UGUI Dropdown下拉控件展开方向控制 有个需要控制下拉控件展开方向的需求,不得探索一下这个下拉方向是由那些属性控制的. 其实我们正常使用的时候你可以发现,下拉控件默认向下展开 ...

  5. android多个下拉控件,Android实现支持所有View的通用的下拉刷新控件

    下拉刷新对于一个app来说是必不可少的一个功能,在早期大多数使用的是chrisbanes的PullToRefresh,或是修改自该框架的其他库.而到现在已经有了更多的选择,github上还是有很多体验 ...

  6. html下拉控件 拼音检索和中文检索,Combobox控件实现汉字按拼音首字母检索

    Combobox控件在开发中作为下拉选项的不二之选,用的非常频繁,前几日开发过程中刚好有个需求有用到这个控件,而且客户要求增加下拉选择功能,这个简单,设置控件的自动完成属性后就解决了this.comb ...

  7. Android 下拉控件Spinner

    Spinner 是android 系统下拉的一个控件 下面分别在把下拉内容在xml 中和java 代码中 来实现操作 1 xml 中 在xml 中创建一个spinner <Spinnerandr ...

  8. 一个简单的PopupWindow做的选项菜单点击按钮会在按钮下弹出几个下拉控件

    为什么80%的码农都做不了架构师?>>>    下载源码 先看效果: 下面是java代码: package com.example.cest;import android.app.A ...

  9. 下拉框、下拉控件之Select2(含多选)

    这个select2组件的功能确实很强大,可以将图片放入到select里面随着文字一起显示. 组件的下载地址以及API说明地址: 1.Select2使用示例地址:https://select2.gith ...

最新文章

  1. Python函数中的参数(一)
  2. iOS SwiftUI篇-1 项目结构
  3. 准备篇--串口通信概述
  4. 警告:failed to load the sqljdbc_auth.dll cause no sqljdbc_auth in java.library.path
  5. Linux系统下MySQL的导出数据语句SELECT … INTO OUTFILE的用法
  6. dp笔记:关于DP算法和滚动数组优化的思考
  7. 重磅!杰青、优青填报界面取消“论文收录与被引统计”
  8. 【python教程入门学习】python值得学吗,怎么自学?
  9. 《Linux命令行与shell脚本编程大全》读书笔记————第一章 初识Linux shell
  10. 【Computer Organization笔记10】单周期CPU设计:基于7条MIPS指令的数据通路
  11. 敏捷开发系列之旅 第四站(透明的Crystal水晶方法) .
  12. 最新可用双端美化版在线音乐播放器网站源码
  13. LS1012ARDB - How to reflash u-boot / RCW via built in Kinetis CMSIS-DAP
  14. win10开机出现任务栏卡死无反应,桌面点击正常,重启任务管理器无效
  15. 51单片机,485,测试03/05/06
  16. nginx本地代理调试微信登录(window版本)
  17. 电路交换,报文交换,分组交换简介与优缺点
  18. 2020年移动发展趋势
  19. docker第二节点无法启动报错xtrabackup_checkpoints missing. xtrabackup/SST failed on DONOR. Check DONOR log解决方案
  20. express hot-reload

热门文章

  1. golang中数组和slice作为参数的区别
  2. Spark LogisticRegression 逻辑回归之建模
  3. ASP.NET Web API 过滤器创建、执行过程(二)
  4. GNU make manual 翻译( 一百二十一)
  5. 完全命令行.NET开发
  6. Django error信息邮件通知功能配置部署
  7. 在Java中使用xpath对xml解析
  8. [大数据] zookeeper 安装和配置
  9. tpopela/vips_java
  10. jQuery学习笔记--Helloworld