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