iOS自定义下拉菜单

释放双眼,带上耳机,听听看~!

这片文章主要描述一下下拉菜单

还是先上代码

@protocol StateViewDelegate <NSObject>
//处理 下拉框中的 点击事件
- (void)selectedCellOfStateView:(NSInteger)row;
@end
@interface StateView : UIView<UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>
///状态数组(下拉菜单中cell的显示内容)
@property (strong, nonatomic) NSArray *stateArr;
///代理
@property (assign, nonatomic) id<StateViewDelegate> delegate;
//初始化控件
- (instancetype)initWithFrame:(CGRect)frame stateArray:(NSArray *)arr;
@end

实现部分

@implementation StateView
- (instancetype)initWithFrame:(CGRect)frame stateArray:(NSArray *)arr{
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.3];
self.stateArr = arr;
//添加手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
tap.delegate = self;
[self addGestureRecognizer:tap];
//添加 状态列表tableView
CGSize tableViewSize = [UIScreen mainScreen].bounds.size;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(tableViewSize.width / 2.0, 64, 0, 0)];
//tableView.layer.borderWidth = 10.0;
tableView.layer.cornerRadius = 5.0;
tableView.bounces = NO;
tableView.backgroundColor = [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1.0];
[UIView transitionWithView:tableView duration:0.4 options:UIViewAnimationOptionTransitionCurlUp animations:^{
tableView.frame = CGRectMake(tableViewSize.width / 4.0, 64, tableViewSize.width / 2.0, 44 * arr.count);
} completion:nil];
tableView.dataSource = self;
tableView.delegate = self;
[self addSubview:tableView];
}
return self;
}
#pragma mark - Action
/**
*  轻拍 手势, 移除控件
*/
- (void)tapAction:(UITapGestureRecognizer *)tap {
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeButtonState" object:nil];
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.stateArr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ID = @"stateID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
cell.textLabel.text = self.stateArr[indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.delegate respondsToSelector:@selector(selectedCellOfStateView:)]) {
[self.delegate selectedCellOfStateView:indexPath.row];
[self tapAction:nil];
}
}
#pragma mark - UIGestureRecognizerDelegate
//手势 代理方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[self class]]) {
return YES;
}else {
return NO;
}
}
@end

调用的时候 也很简单

#import "ViewController.h"
#import "StateView.h"
@interface ViewController ()<StateViewDelegate>{
StateView *stateView;
UIButton *menuBtn;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
menuBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[menuBtn setTitle:@"全部账户" forState:UIControlStateNormal];
[menuBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[menuBtn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
[menuBtn addTarget:self action:@selector(clickTopMenuAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.titleView = menuBtn;
//注册通知, 改变button状态
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeButtonState:) name:@"changeButtonState" object:nil];
}
- (void)clickTopMenuAction:(UIButton *)button {
button.selected = !button.isSelected;
if (button.isSelected) {
NSArray *stateArray = @[@"全部",@"已受理",@"已确认",@"运送中",@"已签收"];
stateView = [[StateView alloc] initWithFrame:[UIScreen mainScreen].bounds stateArray:stateArray];
stateView.delegate = self;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:stateView];
}
}
#pragma mark - notification
/**
*  改变 topButton 为未选中状态
*  从父视图中 移除
*/
- (void)changeButtonState:(NSNotification *)notification {
menuBtn.selected = NO;
[stateView removeFromSuperview];
[menuBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
}
#pragma mark - StateViewDelegate
///下拉菜单 cell选择
- (void)selectedCellOfStateView:(NSInteger)row {
NSLog(@"%ld", row);
}

效果图(只做了个框架, 有点丑, 使用的使用的时候根据自己的需求再做优化)

我只做了个框架

遇到问题

(iOS9.0)开始在下拉菜单的蒙版上添加轻击手势, 但是点击上面的控件tableView上的cell不能响应,而点击事件被其父控件响应, 通俗的讲就是点透事件 或者 穿透事件, 这个问题让我百思不得其解! 按照正常的响应链来说, 子控件能够响应的事件, 父控件就不能响应的, 但是搞不懂为什么子控件本来可以响应的事件为什么不响应了.

解决办法

后来查了好多资料才恍然大悟
tap轻击事件是添加在 父控件上的, 当点击子控件时响应的也是父控件tap的action方法,可以通过证明

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
NSLog(@"%@", touch.view);
}

通过打印你会发现, 当你点击子控件tableView时打印的是UITableView

既然知道了原理了那就简单了, 只需要判断一下touch.view属于哪个类就行了,

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[self class]]) {
return YES;
}else { //只要不是 蒙版 控件都返回NO
return NO;
}
}

人已赞赏
iOS文章

iPad warning:Attempt to present <UIImagePickerController:xxxx > on xxxx which is already presenting (null)

2020-3-6 12:44:16

iOS文章

iOS Realm基本知识

2020-3-6 13:11:53

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索