zoukankan      html  css  js  c++  java
  • 简单下拉列表的实现

    HJDropDownMenu.h

    #import <UIKit/UIKit.h>
    
    @interface HJDropDownMenu : UIView
    
    @property (nonatomic, assign) CGFloat rowHeight;
    
    @property (nonatomic, strong) NSArray * datas;
    
    @property (nonatomic, strong) UIColor *textColor;
    
    @property (nonatomic, strong) UIColor *indicatorColor;
    
    @property (nonatomic, strong) UIFont * font;
    //选中后自动收起
    @property (nonatomic, assign) BOOL autoCloseWhenSelected;
    
    //选中回调
    @property (nonatomic, copy) void(^cellClickedBlock)(NSString *title,NSInteger index);
    
    
    - (void)closeMenu;
    
    
    @end

    HJDropDownMenu.m

    #import "HJDropDownMenu.h"
    #import "UIView+MJExtension.h"
    
    @interface HJDropDownMenu ()<UITableViewDelegate,UITableViewDataSource>
    
    @property (nonatomic, strong) UITableView *listTable;
    
    @property (nonatomic, strong) UIButton *headerBtn;
    
    @property (nonatomic, assign) BOOL headerSelected;
    
    @property (nonatomic, strong) CAShapeLayer *shapeLayer;
    
    
    @end
    
    static NSString * const kDropMenuCellIdentifier = @"DropMenuCellIdentifier";
    static const CGFloat kCellDefaultHeight = 44.f;
    
    @implementation HJDropDownMenu
    
    #pragma mark - Life Circle
    -(instancetype)initWithFrame:(CGRect)frame;{
        self = [super initWithFrame:frame];
        if(self){
            [self configData];
            [self setupUI];
        }
        return self;
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            [self configData];
            [self setupUI];
        }
        return self;
    }
    
    
    - (void)configData{
    
        self.indicatorColor = [UIColor blackColor];
        
        self.textColor = [UIColor blackColor];
        
        self.font = [UIFont systemFontOfSize:14.f];
    
    }
    #pragma mark - About UI
    - (void)setupUI{
    
        self.layer.borderWidth = 0.5f;
        self.layer.borderColor = [UIColor darkGrayColor].CGColor;
        self.layer.cornerRadius = 4.f;
        self.layer.masksToBounds = YES;
        
        [self addSubview:self.listTable];
        
        
        [self.listTable setFrame:CGRectMake(0, 0, self.mj_h, kCellDefaultHeight)];
        [self.listTable registerClass:[UITableViewCell class] forCellReuseIdentifier:kDropMenuCellIdentifier];
    }
    
    
    - (void)layoutSubviews{
        [super layoutSubviews];
        
        if (self.headerSelected) {
            self.mj_h = self.datas.count*self.rowHeight + self.rowHeight;
        }else{
            self.mj_h = self.rowHeight;
        }
        self.listTable.frame = self.bounds;
    }
    #pragma mark - Event response
    - (void)sectionHeaderClicked{
    
        self.headerSelected = !self.headerSelected;
        [self setNeedsLayout];
        __weak typeof(self) weakSelf = self;
        [self animateIndicator:self.shapeLayer Forward:self.headerSelected complete:^{
            [weakSelf cellInsertOrDelete:self.headerSelected];
        }];
        
        
        
        
    }
    #pragma mark - Pravite Method
    - (CAShapeLayer *)createIndicatorWithColor:(UIColor *)color andPosition:(CGPoint)point {
        CAShapeLayer *layer = [CAShapeLayer new];
        
        UIBezierPath *path = [UIBezierPath new];
        [path moveToPoint:CGPointMake(0, 0)];
        [path addLineToPoint:CGPointMake(8, 0)];
        [path addLineToPoint:CGPointMake(4, 5)];
        [path closePath];
        
        layer.path = path.CGPath;
        layer.lineWidth = 1.0;
        layer.fillColor = color.CGColor;
        
        CGPathRef bound = CGPathCreateCopyByStrokingPath(layer.path, nil, layer.lineWidth, kCGLineCapButt, kCGLineJoinMiter, layer.miterLimit);
        layer.bounds = CGPathGetBoundingBox(bound);
        
        CGPathRelease(bound);
        
        layer.position = point;
        
        return layer;
    }
    
    
    - (void)animateIndicator:(CAShapeLayer *)indicator Forward:(BOOL)forward complete:(void(^)())complete {
        [CATransaction begin];
        [CATransaction setAnimationDuration:0.25];
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0.4 :0.0 :0.2 :1.0]];
        
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        anim.values = forward ? @[ @0, @(M_PI) ] : @[ @(M_PI), @0 ];
        
        if (!anim.removedOnCompletion) {
            [indicator addAnimation:anim forKey:anim.keyPath];
        } else {
            [indicator addAnimation:anim forKey:anim.keyPath];
            [indicator setValue:anim.values.lastObject forKeyPath:anim.keyPath];
        }
        
        [CATransaction commit];
        
        complete();
    }
    
    
    - (void)cellInsertOrDelete:(BOOL)insert{
        
        [self.listTable beginUpdates];
        NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:self.datas.count];
        
        [self.datas enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSIndexPath *indexP = [NSIndexPath indexPathForRow:idx inSection:0];
            [indexPaths addObject:indexP];
        }];
        
        if (insert) {
            [self.listTable insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
        }else{
            [self.listTable deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationBottom];
        }
        
        
        
        [self.listTable endUpdates];
    }
    #pragma mark - Public Method
    - (void)closeMenu{
        if (self.headerSelected) {
            [self sectionHeaderClicked];
        }
    }
    #pragma mark - Getters/Setters/Lazy
    - (UITableView *)listTable{
        if (!_listTable) {
            _listTable = [[UITableView alloc] init];
            _listTable.separatorStyle = UITableViewCellSeparatorStyleNone;
            _listTable.delegate = self;
            _listTable.dataSource = self;
        }
        return _listTable;
    }
    
    
    - (void)setDatas:(NSArray *)datas{
        _datas = datas;
        
        [self.listTable reloadData];
    }
    
    
    - (void)setRowHeight:(CGFloat)rowHeight{
        _rowHeight = rowHeight;
        
        [self setNeedsDisplay];
    }
    #pragma mark - Delegate methods
    
    #pragma mark - UITableViewDataSource
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        
        return self.headerSelected?self.datas.count:0;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDropMenuCellIdentifier];
        cell.textLabel.text = self.datas[indexPath.row];
        cell.textLabel.font = self.font;
        cell.textLabel.textColor = self.textColor;
        cell.contentView.layer.borderColor = [UIColor darkGrayColor].CGColor;
        return cell;
    }
    
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        
        return 1;
    }
    
    #pragma mark - UITableViewDelegate
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        
        [self.headerBtn setTitle:self.datas[indexPath.row] forState:UIControlStateNormal];
        
        if(self.cellClickedBlock){
            self.cellClickedBlock(self.datas[indexPath.row], indexPath.row);
        }
        
        
        if (self.autoCloseWhenSelected) {
            [self closeMenu];
        }
        
    }
    
    
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
        
        UIButton *headerBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, tableView.mj_w, self.rowHeight==0?kCellDefaultHeight:self.rowHeight)];
        headerBtn.titleLabel.font = self.font;
        [headerBtn setTitleColor:self.textColor forState:UIControlStateNormal];
        [headerBtn setTitle:self.datas[0] forState:UIControlStateNormal];
        [headerBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
        [headerBtn setTitleEdgeInsets:UIEdgeInsetsMake(0, 15, 0, 0)];
        [headerBtn addTarget:self action:@selector(sectionHeaderClicked) forControlEvents:UIControlEventTouchUpInside];
        
        CGPoint position = CGPointMake(headerBtn.mj_w-10,headerBtn.mj_h/2.f);
        CAShapeLayer *shapeLayer = [self createIndicatorWithColor:self.indicatorColor andPosition:position];
        [headerBtn.layer addSublayer:shapeLayer];
        
        
        self.shapeLayer = shapeLayer;
        self.headerBtn = headerBtn;
        return headerBtn;
    }
    
    
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        return self.rowHeight==0?kCellDefaultHeight:self.rowHeight;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        
        return self.rowHeight==0?kCellDefaultHeight:self.rowHeight;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        
        return 0.001f;
    }
    
    @end

    调用:

    #import "ViewController.h"
    #import "HJDropDownMenu.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        HJDropDownMenu * yearMenu = [[HJDropDownMenu alloc] initWithFrame:CGRectMake(50, 100, 100, 24)];
        yearMenu.rowHeight = 24;
        yearMenu.datas = @[@"2017年",@"2016年",@"2015年",@"2014年"];
        [self.view addSubview:yearMenu];
        
        
        HJDropDownMenu * peomMenu = [[HJDropDownMenu alloc] initWithFrame:CGRectMake(200, 100, 100, 24)];
        peomMenu.rowHeight = 24;
        peomMenu.datas = @[@"蒹葭苍苍",@"白露为霜",@"所谓伊人",@"在水一方",@"溯洄从之",@"道阻且长",@"溯游从之",@"宛在水中央"];
        [self.view addSubview:peomMenu];
    
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
  • 相关阅读:
    vue-cli router的使用
    vue element new vue const
    mac terminal update management pack
    关于MAC升级后,vim更新插件报错
    flex入门----基础知识
    常用的flex知识 ,比起float position 好用不少
    npm 安装nodesass 或者包含nodesass的脚手架工具报错问题
    anglar cli的 rxjs_1.of is not a function
    npm node sass 安装报错
    axios ajax fetch 区别
  • 原文地址:https://www.cnblogs.com/xuzb/p/9554049.html
Copyright © 2011-2022 走看看