您的位置:首页 > 移动开发 > IOS开发

ios 下拉列表

2015-11-09 18:36 351 查看




#import <UIKit/UIKit.h>

@class FVPullDownMenu;

/** 指示器状态*/
typedef enum
{
IndicatorStateShow = 0,
IndicatorStateHide
}
IndicatorStatus;

/** 视图状态*/
typedef enum
{
BackGroundViewStatusShow = 0,
BackGroundViewStatusHide
}
BackGroundViewStatus;

/**  选择回调 协议*/
@protocol FVPullDownMenuDelegate <NSObject>

- (void)PullDownMenu:(FVPullDownMenu *)pullDownMenu didSelectRowAtColumn:(NSInteger)column row:(NSInteger)row;

@end

@interface FVPullDownMenu : UIView<UITableViewDelegate, UITableViewDataSource>

- (FVPullDownMenu *)initWithArray:(NSArray *)array selectedColor:(UIColor *)color;

@property (nonatomic) id<FVPullDownMenuDelegate> delegate;

@end

/** CALayer 扩展*/
@interface CALayer (FVAddAnimationAndValue)

- (void)addAnimation:(CAAnimation *)anim andValue:(NSValue *)value forKeyPath:(NSString *)keyPath;

@end


.m

#import "FVPullDownMenu.h"

@implementation FVPullDownMenu
{

UIColor *_menuColor;

UIView *_backGroundView;
UITableView *_tableView;

NSMutableArray *_titles;
NSMutableArray *_indicators;

NSInteger _currentSelectedMenudIndex;
bool _show;

NSInteger _numOfMenu;

NSArray *_array;

}

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];

if (self) {

}
return self;
}

- (FVPullDownMenu *)initWithArray:(NSArray *)array selectedColor:(UIColor *)color
{
self = [super init];
if (self) {

self.frame = CGRectMake(0, 0, 160, 30);

self.layer.borderWidth = 1;
self.layer.borderColor =  [[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3] CGColor];

_menuColor = [UIColor colorWithRed:164.0/255.0 green:166.0/255.0 blue:169.0/255.0 alpha:1.0];

_array = array;

_numOfMenu = 1; //_array.count; //需要多列的话换成_array.count

CGFloat textLayerInterval = self.frame.size.width / ( _numOfMenu * 2);
CGFloat separatorLineInterval = self.frame.size.width / _numOfMenu;

_titles = [[NSMutableArray alloc] initWithCapacity:_numOfMenu];
_indicators = [[NSMutableArray alloc] initWithCapacity:_numOfMenu];

for (int i = 0; i < _numOfMenu; i++) {

CGPoint position = CGPointMake( (i * 2 + 1) * textLayerInterval , self.frame.size.height / 2);
CATextLayer *title = [self creatTextLayerWithNSString:_array[i][0][@"title"] withColor:_menuColor andPosition:position];
[self.layer addSublayer:title];
[_titles addObject:title];

CAShapeLayer *indicator = [self creatIndicatorWithColor:_menuColor andPosition:CGPointMake(position.x + title.bounds.size.width / 2 + 8, self.frame.size.height / 2)];
[self.layer addSublayer:indicator];
[_indicators addObject:indicator];

if (i != _numOfMenu - 1) {
CGPoint separatorPosition = CGPointMake((i + 1) * separatorLineInterval, self.frame.size.height / 2);
CAShapeLayer *separator = [self creatSeparatorLineWithColor:[UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:243.0/255.0 alpha:1.0] andPosition:separatorPosition];
[self.layer addSublayer:separator];
}

}
_tableView = [self creatTableViewAtPosition:CGPointMake(0, self.frame.origin.y + self.frame.size.height)];
_tableView.tintColor = color;
_tableView.dataSource = self;
_tableView.delegate = self;

// 设置menu, 并添加手势
self.backgroundColor = [UIColor whiteColor];
UIGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapMenu:)];
[self addGestureRecognizer:tapGesture];

// 创建背景
_backGroundView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_backGroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.0];
_backGroundView.opaque = NO;
UIGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapBackGround:)];
[_backGroundView addGestureRecognizer:gesture];

_currentSelectedMenudIndex = -1;
_show = NO;
}
return self;
}

#pragma mark - tapEvent

// 处理菜单点击事件.
- (void)tapMenu:(UITapGestureRecognizer *)paramSender
{

CGPoint touchPoint = [paramSender locationInView:self];

// 得到tapIndex

NSInteger tapIndex = touchPoint.x / (self.frame.size.width / _numOfMenu);

for (int i = 0; i < _numOfMenu; i++) {
if (i != tapIndex) {
[self animateIndicator:_indicators[i] Forward:NO complete:^{
[self animateTitle:_titles[i] show:NO complete:^{
}];
}];
}
}

if (tapIndex == _currentSelectedMenudIndex && _show) {

[self animateIdicator:_indicators[_currentSelectedMenudIndex] background:_backGroundView tableView:_tableView title:_titles[_currentSelectedMenudIndex] forward:NO complecte:^{
_currentSelectedMenudIndex = tapIndex;
_show = NO;

}];

} else {

_currentSelectedMenudIndex = tapIndex;
[_tableView reloadData];
[self animateIdicator:_indicators[tapIndex] background:_backGroundView tableView:_tableView title:_titles[tapIndex] forward:YES complecte:^{
_show = YES;
}];

}

}

- (void)tapBackGround:(UITapGestureRecognizer *)paramSender
{

[self animateIdicator:_indicators[_currentSelectedMenudIndex] background:_backGroundView tableView:_tableView title:_titles[_currentSelectedMenudIndex] forward:NO complecte:^{
_show = NO;
}];

}

#pragma mark - tableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

[self confiMenuWithSelectRow:indexPath.row];
[self.delegate PullDownMenu:self didSelectRowAtColumn:_currentSelectedMenudIndex row:indexPath.row];

}

#pragma mark tableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_array[_currentSelectedMenudIndex] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
cell.textLabel.font = [UIFont systemFontOfSize:13.0];
}

[cell.textLabel setTextColor:[UIColor grayColor]];
[cell setAccessoryType:UITableViewCellAccessoryNone];
cell.textLabel.text = _array[_currentSelectedMenudIndex][indexPath.row][@"title"];

if (cell.textLabel.text == [(CATextLayer *)[_titles objectAtIndex:_currentSelectedMenudIndex] string]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
[cell.textLabel setTextColor:[tableView tintColor]];
}

return cell;
}

#pragma mark - animation

- (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 andValue:anim.values.lastObject forKeyPath:anim.keyPath];
}

[CATransaction commit];

indicator.fillColor = forward ? _tableView.tintColor.CGColor : _menuColor.CGColor;

complete();
}

- (void)animateBackGroundView:(UIView *)view show:(BOOL)show complete:(void(^)())complete
{

if (show) {

[self.superview addSubview:view];
[view.superview addSubview:self];

[UIView animateWithDuration:0.2 animations:^{
view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
}];

} else {
[UIView animateWithDuration:0.2 animations:^{
view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.0];
} completion:^(BOOL finished) {
[view removeFromSuperview];
}];

}
complete();

}

- (void)animateTableView:(UITableView *)tableView show:(BOOL)show complete:(void(^)())complete
{
if (show) {

tableView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height, self.frame.size.width, 0);
[self.superview addSubview:tableView];

CGFloat tableViewHeight = ([tableView numberOfRowsInSection:0] > 5) ? (5 * tableView.rowHeight) : ([tableView numberOfRowsInSection:0] * tableView.rowHeight);

[UIView animateWithDuration:0.2 animations:^{
_tableView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height, self.frame.size.width, tableViewHeight);
}];

} else {

[UIView animateWithDuration:0.2 animations:^{
_tableView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + self.frame.size.height, self.frame.size.width, 0);
} completion:^(BOOL finished) {
[tableView removeFromSuperview];
}];

}
complete();

}

- (void)animateTitle:(CATextLayer *)title show:(BOOL)show complete:(void(^)())complete
{
if (show) {
title.foregroundColor = _tableView.tintColor.CGColor;
} else {
title.foregroundColor = _menuColor.CGColor;
}
CGSize size = [self calculateTitleSizeWithString:title.string];
CGFloat sizeWidth = (size.width < (self.frame.size.width / _numOfMenu) - 25) ? size.width : self.frame.size.width / _numOfMenu - 25;
title.bounds = CGRectMake(0, 0, sizeWidth, size.height);

complete();
}

- (void)animateIdicator:(CAShapeLayer *)indicator background:(UIView *)background tableView:(UITableView *)tableView title:(CATextLayer *)title forward:(BOOL)forward complecte:(void(^)())complete{

[self animateIndicator:indicator Forward:forward complete:^{
[self animateTitle:title show:forward complete:^{
[self animateBackGroundView:background show:forward complete:^{
[self animateTableView:tableView show:forward complete:^{
}];
}];
}];
}];

complete();
}

#pragma mark - drawing

- (CAShapeLayer *)creatIndicatorWithColor:(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;
}

- (CAShapeLayer *)creatSeparatorLineWithColor:(UIColor *)color andPosition:(CGPoint)point
{
CAShapeLayer *layer = [CAShapeLayer new];

UIBezierPath *path = [UIBezierPath new];
[path moveToPoint:CGPointMake(160,0)];
[path addLineToPoint:CGPointMake(160, 20)];

layer.path = path.CGPath;
layer.lineWidth = 1.0;
layer.strokeColor = 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;
}

- (CATextLayer *)creatTextLayerWithNSString:(NSString *)string withColor:(UIColor *)color andPosition:(CGPoint)point
{

CGSize size = [self calculateTitleSizeWithString:string];

CATextLayer *layer = [CATextLayer new];
CGFloat sizeWidth = (size.width < (self.frame.size.width / _numOfMenu) - 25) ? size.width : self.frame.size.width / _numOfMenu - 25;
layer.bounds = CGRectMake(0, 0, sizeWidth, size.height);
layer.string = string;
layer.fontSize = 13.0;
layer.alignmentMode = kCAAlignmentCenter;
layer.foregroundColor = color.CGColor;

layer.contentsScale = [[UIScreen mainScreen] scale];

layer.position = point;

return layer;
}

- (UITableView *)creatTableViewAtPosition:(CGPoint)point
{
UITableView *tableView = [UITableView new];

tableView.frame = CGRectMake(point.x, point.y, self.frame.size.width, 0);
tableView.rowHeight = 25;

return tableView;
}

#pragma mark - otherMethods

- (CGSize)calculateTitleSizeWithString:(NSString *)string
{
CGFloat fontSize = 13.0;
NSDictionary *dic = @{NSFontAttributeName: [UIFont systemFontOfSize:fontSize]};
CGSize size = [string boundingRectWithSize:CGSizeMake(280, 0) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dic context:nil].size;
return size;
}

- (void)confiMenuWithSelectRow:(NSInteger)row
{

CATextLayer *title = (CATextLayer *)_titles[_currentSelectedMenudIndex];

title.string = [[_array objectAtIndex:_currentSelectedMenudIndex] objectAtIndex:row][@"title"];

[self animateIdicator:_indicators[_currentSelectedMenudIndex] background:_backGroundView tableView:_tableView title:_titles[_currentSelectedMenudIndex] forward:NO complecte:^{
_show = NO;

}];

CAShapeLayer *indicator = (CAShapeLayer *)_indicators[_currentSelectedMenudIndex];
indicator.position = CGPointMake(title.position.x + title.frame.size.width / 2 + 8, indicator.position.y);
}

@end

#pragma mark - CALayer Category

@implementation CALayer (FVAddAnimationAndValue)

- (void)addAnimation:(CAAnimation *)anim andValue:(NSValue *)value forKeyPath:(NSString *)keyPath
{
[self addAnimation:anim forKey:keyPath];
[self setValue:value forKeyPath:keyPath];
}

@end


数据格式

数据格式

NSArray * testArray = @[
@[
@{@"title":@"1111@qq.com" ,@"uid": @"111"},
@{@"title":@"2222@qq.com" ,@"uid": @"222"},
@{@"title":@"3333@qq.com" ,@"uid": @"333"}
],
@[@""]
];


使用

NSInteger selectrow;

FVPullDownMenu *menu = [[FVPullDownMenu alloc] initWithArray:_accountArray selectedColor:[UIColor colorWithRed:32/255.0 green:144/255.0 blue:21/255.0 alpha:1.0]];
menu.delegate = self;
menu.frame = CGRectMake(110, 16, 160, 30);
[self.view addSubview:menu];

//委托回调方法
- (void)PullDownMenu:(FVPullDownMenu *)pullDownMenu didSelectRowAtColumn:(NSInteger)column row:(NSInteger)row
{
selectrow = row;
}

//得到选择的数据
NSString * title = testArray[0][selectrow][@"title"];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: