导航栏下拉菜单

1.如何使用?

#import "NavDropDownMenu.h"

然后在控制器初始化方法中:

// 创建导航栏右侧标题按钮
    NSArray *titles = @[@"北京", @"上海", @"天津", @"重庆", @"云南",@"内蒙古", @"吉林", @"四川", @"宁夏", @"安徽", @"山西", @"山东",@"广东", @"广西", @"新疆", @"江苏", @"江西",@"河北", @"河南", @"浙江", @"海南", @"湖北", @"湖南", @"甘肃", @"福建", @"西藏", @"贵州", @"辽宁", @"陕西", @"青海", @"黑龙江"];
    NavDropDownMenu *menuView = [[NavDropDownMenu alloc] initWithFrame:CGRectMake(0, 0,100, 44) titles:titles];
    menuView.selectedAtIndex = ^(int index)
    {
        [self getData:titles[index]];
    };
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:menuView];
2.NavDropDownMenu的代码如下:

//
//  NavDropDownMenu.h

//  应用于导航栏上的下拉菜单控件(点击导航栏上按钮弹出)

#import <UIKit/UIKit.h>

@interface NavDropDownMenu : UIView

/**
 *  导航栏上标题按钮文本颜色,默认 [UIColor colorWithRed:251/255.0 green:85/255.0 blue:1/255.0 alpha:1.0]
 */
@property (nonatomic, strong) UIColor *titleColor;

/**
 *  导航栏上标题按钮字体,默认 [UIFont systemFontOfSize:15]
 */
@property (nonatomic, strong) UIFont *titleFont;


/**
 *  cell中textLabel的文本颜色, 默认[UIColor darkGrayColor]
 */
@property (nonatomic, strong) UIColor *textLabelColor;

@property (nonatomic, strong) UIColor *textLabelHighlightedColor;

/**
 *  cell中textLabel的字体, 默认[UIFont systemFontOfSize:13]
 */
@property (nonatomic, strong) UIFont *textLabelFont;

/**
 *  cell高度
 */
@property (nonatomic, assign) CGFloat cellHeight;


// callback block
/**
 *  点击了哪一个菜单(菜单索引)
 */
@property (nonatomic, copy) void (^selectedAtIndex)(int index);

/**
 *  初始化方法
 *
 *  @param frame  控件在导航栏上面的frame
 *  @param titles 展开菜单数据
 */
- (instancetype)initWithFrame:(CGRect)frame titles:(NSArray*)titles;

@end

//======================TitleButton==================
@interface TitleButton : UIButton

@end
上面几个属性,我没有重写

//
//  NavDropDownMenu.m


#import "NavDropDownMenu.h"

#define ScreenW [UIScreen mainScreen].bounds.size.height
#define ScreenH [UIScreen mainScreen].bounds.size.width

// bgView默认透明度
#define BgViewAlpha 0.3


@interface NavDropDownMenu() <UITableViewDataSource, UITableViewDelegate>

/**
 *  显示在导航栏的按钮
 */
@property (nonatomic, strong) UIButton *titleButton;

/**
 *  展开的菜单数据
 */
@property (nonatomic, copy) NSArray *titles;

/**
 *  用来nonatomic, 展示菜单数据的表格
 */
@property (nonatomic, strong) UITableView *tableView;

/**
 *  当前选中菜单索引
 */
@property (nonatomic, assign) NSUInteger selectedIndex;

/**
 *  菜单是否显示状态
 */
@property (nonatomic, assign) BOOL isMenuShow;

/**
 *  菜单背景视图
 */
@property (nonatomic, strong) UIView *bgView;

/**
 *  最外层的视图(用来包裹bgView和tableView)
 */
@property (nonatomic, strong) UIView *wrapperView;

@end

@implementation NavDropDownMenu


#pragma mark - 重写

/**
 *  重写selectedIndex属性,切换按钮的标题文字
 */
- (void)setSelectedIndex:(NSUInteger)selectedIndex
{
    if (_selectedIndex != selectedIndex)
    {
        _selectedIndex = selectedIndex;
        [_titleButton setTitle:[_titles objectAtIndex:selectedIndex] forState:UIControlStateNormal];
    }
    
    self.isMenuShow = NO;
    self.titleButton.selected = NO;
}

/**
 *  重写isMenuShow属性,控制菜单的显示和隐藏
 */
- (void)setIsMenuShow:(BOOL)isMenuShow
{
    if (_isMenuShow != isMenuShow)
    {
        _isMenuShow = isMenuShow;
        
        if (isMenuShow)
        {
            [self showMenu];
        }
        else
        {
            [self hideMenu];
        }
    }
}

#pragma mark - 菜单的显示和隐藏的方法
/**
 *  展开菜单
 */
- (void)showMenu
{
    self.wrapperView.hidden = NO;
    
    // tableView动画展开
    self.tableView.transform = CGAffineTransformMakeTranslation(0, -ScreenH);
    self.bgView.alpha = 0.0;
    [UIView animateWithDuration:0.25 animations:^{
        self.tableView.transform = CGAffineTransformIdentity;
        self.bgView.alpha = BgViewAlpha;
    }];
}

/**
 *  隐藏菜单
 */
- (void)hideMenu
{
    // tableView动画关闭
    [UIView animateWithDuration:0.25 animations:^{
        self.tableView.transform = CGAffineTransformMakeTranslation(0, -ScreenH);
        self.bgView.alpha = 0.0;
    } completion:^(BOOL finished) {
        self.wrapperView.hidden = YES;
        [self.tableView reloadData];
    }];
}

/**
 *  视图移动到窗口上会调用这个方法
 */
- (void)didMoveToWindow
{
    [super didMoveToWindow];
    
    if (self.window){
        // 把wrapperView添加到窗口上
        self.wrapperView.hidden = YES;
        [self.window addSubview:self.wrapperView];
        
        // wrapperView视图依附于导航栏下面
        self.wrapperView.frame = CGRectMake(0, 64, self.window.bounds.size.width, self.window.bounds.size.height);
     
        // 设置bgView的frame
        self.bgView.frame = self.wrapperView.bounds;

        
        // 设置tableView的frame
        CGFloat  height = _titles.count * _cellHeight;
        if (height >= [UIScreen mainScreen].bounds.size.height * 0.5) {
            height = [UIScreen mainScreen].bounds.size.height * 0.4;
        }
        [self.tableView setFrame:CGRectMake(0, 0, ScreenW, height)];
        
    }else{
        // 避免不能销毁的问题
        [self.wrapperView removeFromSuperview];
    }
}

/**
 *  初始化方法
 */
- (instancetype)initWithFrame:(CGRect)frame titles:(NSArray*)titles
{
    if (self = [super initWithFrame:frame]) {
        // 保存菜单数据
        _titles = titles;
        // 设置标题按钮的frame
        self.titleButton.frame = frame;
        // 默认选择索引为0的菜单
        _selectedAtIndex = 0;
        // 默认菜单是隐藏的
         _isMenuShow = NO;
        // 默认cell高度
         _cellHeight = 38;
        
        [self addSubview:self.titleButton];
        [self.wrapperView addSubview:self.bgView];
        [self.wrapperView addSubview:self.tableView];
    }
    
    return self;
}


#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.titles.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return self.cellHeight;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableViewCell" forIndexPath:indexPath];
    cell.textLabel.text = [self.titles objectAtIndex:indexPath.row];
    cell.textLabel.font = [self textLabelFont];
   
    if (self.selectedIndex == indexPath.row){
         cell.textLabel.textColor = [self textLabelHighlightedColor];
    }else{
        cell.textLabel.textColor = [self textLabelColor];
    }

    
    return cell;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.selectedIndex = indexPath.row;
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (self.selectedAtIndex)
    {
        self.selectedAtIndex((int)indexPath.row);
    }
}

#pragma mark - 懒加载
- (UIButton *)titleButton
{
    if (!_titleButton)
    {
        _titleButton = [[TitleButton alloc] init];
        [_titleButton setTitle:[self.titles objectAtIndex:0] forState:UIControlStateNormal];
        [_titleButton addTarget:self action:@selector(titleButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
        [_titleButton.titleLabel setFont:self.titleFont];
        [_titleButton setTitleColor:self.titleColor forState:UIControlStateNormal];
    }
    
    return _titleButton;
}

/**
 *  _titleButton的监听方法
 */
- (void)titleButtonClicked:(UIButton *)button
{
    self.isMenuShow = !self.isMenuShow;
    self.titleButton.selected = !self.titleButton.selected;
}

- (UIColor *)titleColor
{
    if (!_titleColor)
    {
        _titleColor = [UIColor colorWithRed:251/255.0 green:85/255.0 blue:1/255.0 alpha:1.0];
    }
    
    return _titleColor;
}

- (UIFont *)titleFont
{
    if (!_titleFont) {
        _titleFont = [UIFont systemFontOfSize:15];
    }
    return _titleFont;
}

- (UITableView *)tableView
{
    if (!_tableView)
    {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height * 0.5)];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.tableFooterView = [[UIView alloc] init];
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"tableViewCell"];
    }
    
    return _tableView;
}

- (UIView *)bgView
{
    if (!_bgView){
        
        _bgView = [[UIView alloc] init];
        _bgView.backgroundColor = [UIColor blackColor];
        _bgView.alpha = BgViewAlpha;
        
        // bgView触摸事件
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(bgViewClicked)];
        [_bgView addGestureRecognizer:tap];
    }
    
    return _bgView;
}

- (void)bgViewClicked
{
    [self titleButtonClicked:nil];
}

- (UIView *)wrapperView
{
    if (!_wrapperView)
    {
        _wrapperView = [[UIView alloc] init];
        _wrapperView.clipsToBounds = YES;
    }
    
    return _wrapperView;
}

- (UIFont *)textLabelFont
{
    if (!_textLabelFont) {
        _textLabelFont = [UIFont systemFontOfSize:13];
    }
    return _textLabelFont;
}

- (UIColor *)textLabelColor
{
    if (!_textLabelColor) {
        _textLabelColor = [UIColor darkGrayColor];
    }
    return _textLabelColor;
}

- (UIColor *)textLabelHighlightedColor
{
    if (!_textLabelHighlightedColor) {
        _textLabelHighlightedColor = [UIColor colorWithRed:251/255.0 green:85/255.0 blue:1/255.0 alpha:1.0];
    }
    return _textLabelHighlightedColor;
}

@end

//======================TitleButton==================
@implementation TitleButton

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // 图片内容模式:居中
        self.imageView.contentMode = UIViewContentModeCenter;
        [self setImage:[UIImage imageNamed:@"nav_screening_down_normal"] forState:UIControlStateNormal];
        [self setImage:[UIImage imageNamed:@"nav_screening_down_pressed"] forState:UIControlStateHighlighted];
        [self setImage:[UIImage imageNamed:@"nav_screening_up_normal"] forState:UIControlStateSelected];
        
        // 文字右对齐
        self.titleLabel.textAlignment = NSTextAlignmentRight;
    }
    
    return self;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGFloat titleW = contentRect.size.width - 11 - 5;
    CGFloat titleH = contentRect.size.height;
    
    return CGRectMake(0, 0, titleW, titleH);
}

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    
    CGFloat imageW = 11;
    CGFloat imageH = contentRect.size.height;
    CGFloat imageX = contentRect.size.width - imageW;
    
    return CGRectMake(imageX, 0, imageW, imageH);
}


@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值