下拉菜单

记录一下这两天的成果: 下拉菜单 和 抽屉.
这片文章主要描述一下下拉菜单

还是先上代码

@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);
}

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

下拉菜单_第1张图片

遇到问题

(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;
    }
}

你可能感兴趣的:(下拉菜单)