A while ago, received a demand, need to achieve the left side of the display category list, the right part of the page to achieve two types of and subclass data, and can realize the sliding up and down as well as radio multiple selection, and can have selected data to the need to use the page. The following is the finished diagram as implemented

## Implementation process:

New MultilevelMenu class, inherited from UIView, the purpose of this class is to add leftTableView on the left, rightCollectionView on the right, data assignment and provide external interface for custom development.

Multilevelmenu. h, RightMenu model class, used to record the value of button menu, menu ID, and parent class ID code:

typedef void(^ChooseBlock) (NSString *chooseContent,NSMutableArray *chooseArr); @interface MultilevelMenu : UIView<UITableViewDataSource,UITableViewDelegate,UICollectionViewDelegateFlowLayout,UICollectionViewDataSource,UICollect ionViewDelegate> @property(strong,nonatomic,readonly) NSArray * allData; / / @property(assign,nonatomic) BOOL isRecordLastScroll; / * * * record sliding position need animation * / @ property (the assign, nonatomic) BOOL isRecordLastScrollAnimated; / * * * record has been selected data index * / @ property (assign nonatomic, readonly) NSInteger selectIndex; /** * left background color */ @property(strong,nonatomic) UIColor * leftBgColor; @property(strong,nonatomic) UIColor * leftSelectColor; /** * @property(strong,nonatomic) UIColor * leftSelectBgColor; @property(nonatomic,copy)ChooseBlock ChooseBlock; @property (nonatomic,assign)BOOL ifAllSelected; @property (nonatomic,assign)BOOL ifAllSelecteSwitch; @property(strong,nonatomic ) UICollectionView * rightCollection; -(instancetype)initWithFrame:(CGRect)frame WithData:(NSArray*)data withSelectIndex:(void(^)(NSInteger left,NSInteger right,id info))selectIndex; @endCopy the code

In the.m file, it is mainly to create two sliding views, slide related processing in the inside, assign value to the View, single and multiple choice of logic, because there are many codes, only the main logic code is listed here, please refer to demo for the complete version

@interface MultilevelMenu()<WaterFlowLayoutDelegate> @property(strong,nonatomic ) UITableView * leftTablew; @property(assign,nonatomic) BOOL isReturnLastOffset; @property(nonatomic,strong) NSMutableArray *headerBtnArr; @end -(void)setNeedToScorllerIndex:(NSInteger)needToScorllerIndex{/** * slide to the specified number of rows */ [self.lefttablew selectRowAtIndexPath:[NSIndexPath indexPathForRow:needToScorllerIndex inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop]; _selectIndex=needToScorllerIndex; [self.rightCollection reloadData]; _needToScorllerIndex=needToScorllerIndex; } -(void)setLeftTablewCellSelected:(BOOL)selected withCell:(MultilevelTableViewCell*)cell { UILabel * line=(UILabel*)[cell viewWithTag:kCellRightLineTag]; if (selected) { line.backgroundColor=cell.backgroundColor; cell.titile.textColor=self.leftSelectColor; cell.backgroundColor=self.leftSelectBgColor; } else{ cell.titile.textColor=self.leftUnSelectColor; cell.backgroundColor=self.leftUnSelectBgColor; line.backgroundColor=_leftTablew.separatorColor; } } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString * Identifier=@"MultilevelTableViewCell"; MultilevelTableViewCell * cell=[tableView dequeueReusableCellWithIdentifier:Identifier]; cell.selectionStyle=UITableViewCellSelectionStyleNone; if (! cell) { cell=[[NSBundle mainBundle] loadNibNamed:@"MultilevelTableViewCell" owner:self options:nil][0]; UILabel * label=[[UILabel alloc] initWithFrame:CGRectMake(kleftwidth-0.5, 0, 0.5, 44)]; label.backgroundColor = tableView.separatorColor; [cell addSubview:label]; label.numberOfLines = 0; label.tag = kCellRightLineTag; } cell.selectionStyle=UITableViewCellSelectionStyleNone; rightMeun * title=self.allData[indexPath.row]; cell.titile.text = title.meunName; cell.titile.font = [UIFont systemFontOfSize:13]; if (indexPath.row==self.selectIndex) { [self setLeftTablewCellSelected:YES withCell:cell]; }else{ [self setLeftTablewCellSelected:NO withCell:cell]; If ([cell respondsToSelector:@selector(setLayOutNavigation :)]) {cell.layOutNavigation =UIEdgeInsetsZero; } if ([cell respondsToSelector:@selector(setSeparatorInset:)]) { cell.separatorInset=UIEdgeInsetsZero; } return cell; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{// returns based on the number of menu subclasses rightMeun * title=self.allData[self.selectIndex]; if (title.nextArray.count>0) { rightMeun *sub=title.nextArray[section]; If (sub.nextarray. count==0)// No lower level {return 1; } else return sub.nextArray.count; } else{ return title.nextArray.count; }} // When I click leftTableView, -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ MultilevelTableViewCell * cell=(MultilevelTableViewCell*)[tableView cellForRowAtIndexPath:indexPath]; _selectIndex = indexPath.row; [self setLeftTablewCellSelected:YES withCell:cell]; rightMeun *title=self.allData[indexPath.row]; [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; self.isReturnLastOffset=NO; //important [self.rightCollection reloadData]; if (self.isRecordLastScroll) { [self.rightCollection scrollRectToVisible:CGRectMake(0, title.offsetScorller, self.rightCollection.frame.size.width, self.rightCollection.frame.size.height) animated:self.isRecordLastScrollAnimated]; } else{ [self.rightCollection scrollRectToVisible:CGRectMake(0, 0, self.rightCollection.frame.size.width, self.rightCollection.frame.size.height) animated:self.isRecordLastScrollAnimated]; } } - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView ViewForSupplementaryElementOfKind: (nsstrings *) kind atIndexPath: (indexPath NSIndexPath *) {/ / with the current selected array and compare all the source data in the section, If (_choosedarr. count > 0) {isContain2 = [[testArr1 copy] isEqual:menuArr]; }else{ isContain2 = false; } if (isContain2) { [chooseIcon setSelected:YES]; }else{ [chooseIcon setSelected:NO]; } } -(void)ChooseAllClick:(UIButton *)button{ NSInteger sectionIndex = button.tag; BOOL selectType = button.isSelected; rightMeun *title = self.allData[self.selectIndex]; // Get the selected item rightMeun *menu; menu = title.nextArray[sectionIndex]; NSArray *selectArr = menu.nextArray; If (_choosedarr.count == 0) {if (_choosedarr.count == 0) { SelectType) {/ / selected [_choosedArr addObjectsFromArray: selectArr]; }} else {the if (selectType) {/ / remove the array data [_choosedArr removeObjectsInArray: selectArr]; } else {/ / added to the array [_choosedArr removeObjectsInArray: selectArr]; [_choosedArr addObjectsFromArray:selectArr]; }} // Record the selected data and update the view _ifAllSelecteSwitch = YES; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:button.tag]; NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndex:indexPath.section]; [_rightCollection reloadSections:indexSet]; }Copy the code

Vc call, 1: need to prepare the array element “allData” required by the business code (which is the rightMenu model), including the first-level menu ID, first-level menu title, second-level menu ID, second-level menu title. 2: Create MultilevelMenu and add it to vc.view

MultilevelMenu * view = [[MultilevelMenu alloc] initWithFrame:CGRectMake(x, y, width, height) WithData: ^(NSInteger left, NSInteger right,rightMeun* info) {NSLog(@" this is a callback ");}]; view.needToScorllerIndex = 0; view.isRecordLastScroll = YES; View. leftSelectColor = [UIColor colorWithHexString:@"#E8340C" alpha:1.0f]; view.choosedArr = [self.selectedArrs mutableCopy]; view.chooseBlock = ^(NSString *chooseContent, NSMutableArray *chooseArr) { }; // [view.rightCollection reloadData]; self.cateView = view; [self.view addSubview:self.cateView];Copy the code

Attached is the demo link: Demo