# MMComboBox **Repository Path**: jingfu/mmcombobox ## Basic Information - **Project Name**: MMComboBox - **Description**: 仿照大众点评APP的筛选框 - **Primary Language**: Objective-C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2017-04-06 - **Last Updated**: 2020-12-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ##前言 本demo基于开源代码所更改 https://github.com/YYWDark/MMComboBox。 0.使用方法 ``` 可使用pod安装,不过需要单独指定spec source source 'https://git.oschina.net/jingfu/JFSpec.git' pod 'MMCombobox' 如果有权限问题,请邮件联系a20251313@163.com ``` ###demo: ![demo.mov](https://github.com/a20251313/MMComboBox/blob/master/demo.mov) ###工程结构图: ![结构图.png](http://upload-images.jianshu.io/upload_images/307963-97fa9a27aa16c8e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1.模拟组装数据,因为可能是多层的,所以我们这里通过组合模式来组装数据。在`MMBaseItem`里面我们定义了四个枚举: ``` //这个字段我们暂时留着以后扩展,覆盖可能要有些选项不能选择,显示灰色的情况 typedef NS_ENUM(NSUInteger, MMPopupViewMarkType) {  //选中的状态     MMPopupViewDisplayTypeSelected = 0,      //可以选中     MMPopupViewDisplayTypeUnselected = 1,    //不可以选中 }; typedef NS_ENUM(NSUInteger, MMPopupViewSelectedType) {     //是否支持单选或者多选     MMPopupViewSingleSelection,                            //单选     MMPopupViewMultilSeMultiSelection,                    //多选 }; typedef NS_ENUM(NSUInteger, MMPopupViewDisplayType) {  //分辨弹出来的view类型     MMPopupViewDisplayTypeNormal = 0,                //一层     MMPopupViewDisplayTypeMultilayer = 1,            //两层     MMPopupViewDisplayTypeFilters = 2,               //混合 }; typedef NS_ENUM(NSInteger, MMPopupViewIconType) { //筛选层附加icon定义 MMPopupViewNoneIcon = 0, //没有图标 MMPopupViewLocationIcon = 1, //位置图标 //kLocationIcon MMPopupViewSortIcon = 2, //排序图标 //kSortedIcon MMPopupViewTypeIcon = 3, //类型图标 //kTypeIcon MMPopupViewFilterIcon = 4, //筛选图标 //kFilterIcon MMPopupViewFloorIcon = 5 //楼层图标 //kFloorIcon }; ``` 每个`MMItem`都持有一个`layout`对象提前计算好弹出视图的布局信息并储存。由于`MMPopupViewDisplayTypeNormal`和`MMPopupViewDisplayTypeMultilayer`两种类型布局比较单一简单,所以`layout`对象暂时只是在`MMPopupViewDisplayTypeFilters`时有用。 当然我这里是模拟数据。下面给出一种建立树模型的思路: ![屏幕快照 2016-12-22 下午11.14.13.png](http://upload-images.jianshu.io/upload_images/307963-7708a77530870004.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1.1 首先我们把上图的根节点放到队列中 ![1.1.png](http://upload-images.jianshu.io/upload_images/307963-ae6a2e9ef9e6df53.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1.2 根据A持有子节点的指针把B,C放进队列,相当于把B,C添加到A的`childrenNodes`。然后把A给移出队列。 ![1.2](http://upload-images.jianshu.io/upload_images/307963-5cfa962948165968.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1.3 然后按照上面的逻辑一个一个的遍历每个节点。直到队列为空的时候代表一颗建立完毕。下面图未给全,只是部分状态的时刻图。 ![1.3.png](http://upload-images.jianshu.io/upload_images/307963-4380f8b8e57539c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![1.4.png](http://upload-images.jianshu.io/upload_images/307963-82c04ee55e654461.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![1.5.png](http://upload-images.jianshu.io/upload_images/307963-4f08f95a88d1887c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 2.初始化视图: ``` /** 初始化MMComBoBoxView @param frame frame @param spaceMargin 上下留白的距离` @return MMComBoBoxView */ - (id)initWithFrame:(CGRect)frame spaceToTop:(CGFloat)spaceMargin; 例子: MMComBoBoxView *view = [[MMComBoBoxView alloc] initWithFrame:CGRectMake(0, 64, kScreenWidth, 40) spaceTop:5];     view.dataSource = self;     view.delegate = self;     [self.view addSubview:view];     [view reload]; ``` 3.通过datasource协议将数据传给`MMComBoBoxView`,你可以联想UITableView数据驱动方式就可以了。 ``` #pragma mark - MMComBoBoxViewDataSource - (NSUInteger)numberOfColumnsIncomBoBoxView :(MMComBoBoxView *)comBoBoxView {     return self.mutableArray.count; } - (MMItem *)comBoBoxView:(MMComBoBoxView *)comBoBoxView infomationForColumn:(NSUInteger)column {     return self.mutableArray[column]; } ``` 4.我们会通过`MMComBoBoxViewDelegate`协议把选中的路径回调出来,这里我们选择回调存储路径的数组的本质是在于可能开发人员上传的不止是`title`,可能还有对应的`code`等一系列的字段。这样方便扩展。 ``` #pragma mark - MMComBoBoxViewDelegate - (void)comBoBoxView:(MMComBoBoxView *)comBoBoxViewd didSelectedModelsInArray:(NSArray *)array atIndex:(NSUInteger)index { for (MMItem *rootItem in array) { NSLog(@"rootItem.key:%@, rootItem.code:%@,rootItem.key2:%@,rootItem.code2:%@,rootItem.title:%@\n",rootItem.key,rootItem.code,rootItem.key2,rootItem.code2,rootItem.title) } } 当筛选框弹出来和收起来会有回调 #pragma mark -- MMComBoBoxViewDelegate 筛选弹出或收起下拉框 - (void)comBoBoxView:(MMComBoBoxView *)comBoBoxViewd actionType:(MMComBoBoxViewShowActionType)action atIndex:(NSUInteger)index { switch (action) { //弹出 case MMComBoBoxViewShowActionTypePop: { CGPoint point = self.placeTableView.contentOffset; if (point.y < self.placeTableView.tableHeaderView.height) { [self.placeTableView setContentOffset:CGPointMake(0, self.placeTableView.tableHeaderView.height)]; } break; } //收起 case MMComBoBoxViewShowActionTypePackUp: break; default: break; } if (self.scrollButtonDelegate && [self.scrollButtonDelegate respondsToSelector:@selector(checkScrollToTopButtonStatus)]) { [self.scrollButtonDelegate checkScrollToTopButtonStatus]; } } ``` 5.设置当前筛选项的title,以及当前选中的值: ``` /** 根据boxValues 设置当前筛选项的title,以及当前选中的值 @param boxValues MMComBoxOldValue */ - (void)updateValueWithData:(NSArray *)boxValues; ``` 6.收起下拉框: ``` /** 收起下拉框 */ - (void)dimissPopView; ```