Menu菜单-水平

  • 已经封装好

  • 导入这个文件就可以使用

  • .h文件

#import <UIKit/UIKit.h>


//需自定义按钮请修改此类
@interface WMMenuButton : UIButton

@end
//需自定义数据模型请更改此类
@interface chdModel : NSObject
@property (nonatomic,copy) NSString *text;
@property BOOL isSub;
@property BOOL isSelect;
@end
//需自定义下拉cell请更改此类
@interface chdMenuCell : UITableViewCell
@property (nonatomic,retain) UIView *bgView;
@property (nonatomic,retain) UIView *point;
@property (nonatomic,retain) UILabel *textL;
@end

@protocol chdMenuDelegate <NSObject>

- (void)selectColum:(NSInteger)colum Row:(NSInteger)row Model:(chdModel*)model;

@end

@interface WMMenu : UIView<UITableViewDataSource,UITableViewDelegate>
- (void)initWithFrame:(CGRect)frame showOnView:(UIView*)view AllDataArr:(NSMutableArray*)arr showArr:(NSMutableArray *)showArr;
//使某列某行被选中,默认均选中第0行。 可调用此方法更改默认。
- (void)selectClum:(NSInteger)colum Row:(NSInteger)row;
@property (nonatomic,retain) NSMutableArray *AllDataArr;
@property (nonatomic,retain) NSMutableArray *showArr;
@property (nonatomic,weak) __weak id<chdMenuDelegate>delegate;

@end

  • .m文件
#import "WMMenu.h"
#import "UIView+WMExtension.h"
#define CHD_SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define CHD_SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)

static const CGFloat cellHeight = 40.0f;

@implementation WMMenuButton

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(CGRectGetWidth(contentRect) - 20,(CGRectGetHeight(contentRect) - 7)/2, 12, 7);
}
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(0, 0, CGRectGetWidth(contentRect) - 15, CGRectGetHeight(contentRect));
}
@end

@implementation chdModel

@end


@implementation chdMenuCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if ([super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        
        self.bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CHD_SCREEN_WIDTH, cellHeight)];
        [self.contentView addSubview:_bgView];
        
        self.point = [[UIView alloc] initWithFrame:CGRectMake(10, (cellHeight - 3)/2.0, 3, 3)];
        self.point.layer.masksToBounds = YES;
        self.point.layer.cornerRadius = 1.5;
        [self.bgView addSubview:_point];
        
        self.textL = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_point.frame)+5, 0,300, cellHeight)];
        self.textL.font = [UIFont systemFontOfSize:12.0f];
        [self.bgView addSubview:_textL];
        
    }
    return self;
}

@end

@implementation WMMenu
{
    UITableView *ChdTable;
    NSInteger currentSelect;
    CGRect orginalFrame;
    BOOL isShow;
    UIView *bgView;
}

- (void)initWithFrame:(CGRect)frame showOnView:(UIView*)view AllDataArr:(NSMutableArray*)arr showArr:(NSMutableArray *)showArr
{
    if ([super initWithFrame:frame]) {
        self.AllDataArr = arr;
        self.showArr = showArr;
        if (!showArr) {
            self.showArr = arr;
        }
        
        for (int i=0; i<arr.count; i++) {
            WMMenuButton *button = [[WMMenuButton alloc] initWithFrame:CGRectMake(i*(CGRectGetWidth(frame)/arr.count), 0, CGRectGetWidth(frame)/arr.count, CGRectGetHeight(frame))];
            button.tag = 100 + i;
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            NSArray *temp = self.showArr[i];
            chdModel *model = [temp firstObject];
            [button setTitle:model.text forState:UIControlStateNormal];
            button.titleLabel.textAlignment = NSTextAlignmentCenter;
            button.backgroundColor = [UIColor whiteColor];
            button.layer.borderColor = [UIColor grayColor].CGColor;
            button.layer.borderWidth = 0.4;
            // 设置箭头图片
            [button setImage:[UIImage imageNamed:@"up1"] forState:UIControlStateNormal];
            button.imageView.transform = CGAffineTransformMakeRotation(M_PI);
            [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
            [self addSubview:button];
            [view addSubview:self];
            
            //
            currentSelect = 0;
            [self selectClum:i Row:0];
            
        }
        
        ChdTable = [[UITableView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.frame), CHD_SCREEN_WIDTH, CHD_SCREEN_HEIGHT - CGRectGetMaxY(self.frame))];
        orginalFrame = CGRectMake(0, CGRectGetMaxY(frame), CHD_SCREEN_WIDTH, 0);
        ChdTable.delegate = self;
        ChdTable.dataSource = self;
        ChdTable.hidden = YES;
        //ChdTable.backgroundColor = [UIColor redColor];
        
        bgView = [[UIView alloc] initWithFrame:orginalFrame];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
        [tap addTarget:self action:@selector(bgViewClick:)];
        [bgView addGestureRecognizer:tap];
        bgView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
        [view addSubview:bgView];
        
        if ([ ChdTable respondsToSelector:@selector(setSeparatorInset:)]) {
            
            [ChdTable   setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
            
        }
        if ([ChdTable respondsToSelector:@selector(setLayoutMargins:)]) {
            
            [ChdTable setLayoutMargins:UIEdgeInsetsMake(0, 0, 0, 0)];
            
        }
        
        [view addSubview:ChdTable];
        self.backgroundColor = [UIColor orangeColor];
    }
    
}
- (void)bgViewClick:(UITapGestureRecognizer*)tap
{
    [self hideCurrent];
    bgView.frame = orginalFrame;
}
- (void)selectClum:(NSInteger)colum Row:(NSInteger)row
{
    //默认选中第一个
    NSArray *temp = self.AllDataArr[colum];
    for (int i=0; i<temp.count; i++) {
        chdModel *model = temp[i];
        if (i == row) {
            model.isSelect = YES;
        }else{
            model.isSelect = NO;
        }
    }
    //[ChdTable reloadData];
    
    NSArray *arr = self.subviews;
    WMMenuButton *btn = (WMMenuButton*)arr[colum];
    chdModel *model = self.showArr[colum][row];
    [btn setTitle:model.text forState:UIControlStateNormal];
}

- (void)buttonClick:(WMMenuButton*)button
{
    if (button.tag - 100 == currentSelect) {
        if (isShow) {
            [self hideCurrent];
        }else{
            [self showIndex:button.tag - 100];
        }
        isShow = !isShow;
    }else{
        [self showIndex:button.tag - 100];
        isShow = YES;
    }
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_AllDataArr[currentSelect] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *chdResuseID = @"CHD_RESUSE";
    
    chdMenuCell *cell = [tableView dequeueReusableCellWithIdentifier:chdResuseID];
    
    if (cell == nil) {
        cell = [[chdMenuCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:chdResuseID];
    }
    
    chdModel * model = [_AllDataArr[currentSelect] objectAtIndex:indexPath.row];
    cell.textL.text = model.text;
    if (model.isSub) {
        cell.bgView.wm_x = 25;
    }else{
        cell.bgView.wm_x = 0;
    }
    if (model.isSelect) {
        cell.textL.textColor = [UIColor blueColor];
    }else{
        cell.textL.textColor = [UIColor blackColor];
    }
    return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        
        [cell setSeparatorInset:UIEdgeInsetsZero];
        
    }
    
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        
        [cell setLayoutMargins:UIEdgeInsetsZero];
        
    }
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return cellHeight;
}
- (void)showIndex:(NSInteger)index
{
    
    if (currentSelect != index) {
        WMMenuButton *btn = self.subviews[currentSelect];
        [UIView animateWithDuration:0.2 animations:^{
            btn.imageView.transform = CGAffineTransformMakeRotation(M_PI);
        }];
    }
    
    currentSelect = index;
    [self realShow];
    
}
- (void)realShow
{
    
    
    ChdTable.hidden = YES;
    ChdTable.wm_height = cellHeight * [_AllDataArr[currentSelect] count];
    [ChdTable reloadData];
    
    bgView.wm_height = CHD_SCREEN_HEIGHT - CGRectGetMaxY(self.frame);
    
    ChdTable.frame = orginalFrame;
    ChdTable.hidden = NO;
    
    WMMenuButton *btn = self.subviews[currentSelect];
    
    [UIView animateWithDuration:0.2 animations:^{
        if (cellHeight * [_AllDataArr[currentSelect] count]>CHD_SCREEN_HEIGHT-CGRectGetMaxY(self.frame)) {
            ChdTable.wm_height = CHD_SCREEN_HEIGHT - CGRectGetMaxY(self.frame);
        }else{
            ChdTable.wm_height = cellHeight * [_AllDataArr[currentSelect] count];
        }
        btn.imageView.transform = CGAffineTransformMakeRotation(0);
    }];
}
- (void)hideCurrent
{
    WMMenuButton *btn = self.subviews[currentSelect];
    [UIView animateWithDuration:0.2 animations:^{
        ChdTable.frame = orginalFrame;
        btn.imageView.transform = CGAffineTransformMakeRotation(M_PI);
    }];
    bgView.frame = orginalFrame;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    
    //*************  本段代码用于选择相同选项时不在回调,不需要可注掉  ****************
    chdModel *modelLast = self.AllDataArr[currentSelect][indexPath.row];
    if (modelLast.isSelect) {
        [self hideCurrent];
        isShow = NO;
        
        return;
    }
    //*************  本段代码用于选择相同选项时不在回调,不需要可注掉  ****************
    
    
    
    [self selectClum:currentSelect Row:indexPath.row];
    [self hideCurrent];
    isShow = NO;
    chdModel *model = self.AllDataArr[currentSelect][indexPath.row];
    if ([self.delegate respondsToSelector:@selector(selectClum:Row:)]) {
        [self.delegate selectColum:currentSelect Row:indexPath.row Model:model];
    }
    NSLog(@"%@",model.text);
    
}

@end
  • 使用实例
#import "ViewController.h"
#import "WMMenu.h"
#define CHD_SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //列表展示的模型
    NSMutableArray *arr = [NSMutableArray array];
    for (int i =0; i<3; i++) {// 3 列
        NSMutableArray *temp = [NSMutableArray array];//
        NSInteger row = (i+1)*3;// 3 6 9 行
        for (int j =0; j<row; j++) { //
            chdModel *model = [[chdModel alloc] init];
            model.text = [NSString stringWithFormat:@"第%@列---第%@行",@(i),@(j)];
            if (( i == 2 && j >= 2 && j < 4) || ( i == 2 && j == 7)) {
                model.isSub = YES;
            }
            
            [temp addObject:model];// ==组的row
        }
        [arr addObject:temp]; // == 组
    }
    
    //上边按钮展示的模型,此模型对text赋值即可.
    NSMutableArray *ShowArr = [NSMutableArray array];
    for (int i =0; i<3; i++) { // 3列
        NSMutableArray *temp = [NSMutableArray array];
        NSInteger row = (i+1)*3;
        for (int j =0; j<row; j++) {
            chdModel *model = [[chdModel alloc] init];
            model.text = [NSString stringWithFormat:@"%@-%@",@(i),@(j)];
            [temp addObject:model];
        }
        [ShowArr addObject:temp];
    }
    
    [[WMMenu alloc] initWithFrame:CGRectMake(0, 40,CHD_SCREEN_WIDTH, 40) showOnView:self.view AllDataArr:arr showArr:ShowArr];
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
效果图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,029评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 对于膜,最初觉得不过是调侃而已,但仔细思考下来,这种风气很不对,用膜去神化更努力的人,来掩盖自己不勤奋,不管什么时...
    永矢弗告阅读 213评论 0 0
  • 老天确实给我机会了,我只是没能抓到。然后,这个月也是结束了,一切都变的被动了。
    常小识阅读 498评论 0 1
  • 在外面碰到他,于是我们悄悄和好了,还没告诉家里人。 去海边玩,景色很漂亮,自拍的时候总是不对,拍出的照片和当时摆的...
    裳璎珞阅读 209评论 0 1