.h
@interface QQPopMenuView : UIView
@property (nonatomic, copy) void (^hideHandle)();
/**
* 實例化方法
*
* @param array items灵寺,包含字典殖卑,字典里面包含標題(title)识颊、圖片名(imageName)
* @param width 寬度
* @param point 三角的頂角坐標(基于window)
* @param action 點擊回調(diào)
*/
- (instancetype)initWithItems:(NSArray <NSDictionary *>*)array
width:(CGFloat)width
triangleLocation:(CGPoint)point
action:(void(^)(NSInteger index))action;
/**
* 類方法展示
*
* @param array items浩嫌,包含字典钠糊,字典里面包含標題(title)垫言、圖片名(imageName)
* @param width 寬度
* @param point 三角的頂角坐標(基于window)
* @param action 點擊回調(diào)
*/
+ (void)showWithItems:(NSArray <NSDictionary *>*)array
width:(CGFloat)width
triangleLocation:(CGPoint)point
action:(void(^)(NSInteger index))action;
- (void)show;
- (void)hide;
@end
.m
#import "QQPopMenuView.h"
#import "PopMenuTableViewCell.h"
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
static CGFloat const kCellHeight = 44;
@interface QQPopMenuView ()<UITableViewDelegate,UITableViewDataSource,UIGestureRecognizerDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSArray *tableData;
@property (nonatomic, assign) CGPoint trianglePoint;
@property (nonatomic, copy) void(^action)(NSInteger index);
@end
@implementation QQPopMenuView
- (instancetype)initWithItems:(NSArray <NSDictionary *>*)array
width:(CGFloat)width
triangleLocation:(CGPoint)point
action:(void(^)(NSInteger index))action
{
if (array.count == 0) {
return nil;
}
if (self = [super init]) {
self.frame = [UIScreen mainScreen].bounds;
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
self.alpha = 0;
_tableData = [array copy];
_trianglePoint = point;
self.action = action;
// 添加手勢
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
tap.delegate = self;
[self addGestureRecognizer:tap];
// 創(chuàng)建tableView
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH - width - 5, point.y + 10, width, kCellHeight * array.count) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.layer.masksToBounds = YES;
_tableView.layer.cornerRadius = 5;
_tableView.scrollEnabled = NO;
_tableView.rowHeight = kCellHeight;
[_tableView registerNib:[UINib nibWithNibName:@"PopMenuTableViewCell" bundle:nil] forCellReuseIdentifier:@"PopMenuTableViewCell"];
[self addSubview:_tableView];
}
return self;
}
+ (void)showWithItems:(NSArray <NSDictionary *>*)array
width:(CGFloat)width
triangleLocation:(CGPoint)point
action:(void(^)(NSInteger index))action
{
QQPopMenuView *view = [[QQPopMenuView alloc] initWithItems:array width:width triangleLocation:point action:action];
[view show];
}
- (void)tap {
[self hide];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
return NO;
}
return YES;
}
#pragma mark - Show or Hide
- (void)show {
[[UIApplication sharedApplication].keyWindow addSubview:self];
// 設(shè)置右上角為transform的起點(默認是中心點)
_tableView.layer.position = CGPointMake(SCREEN_WIDTH - 5, _trianglePoint.y + 10);
// 向右下transform
_tableView.layer.anchorPoint = CGPointMake(1, 0);
_tableView.transform = CGAffineTransformMakeScale(0.0001, 0.0001);
[UIView animateWithDuration:0.2 animations:^{
self.alpha = 1;
_tableView.transform = CGAffineTransformMakeScale(1.0, 1.0);
}];
}
- (void)hide {
[UIView animateWithDuration:0.2 animations:^{
self.alpha = 0;
_tableView.transform = CGAffineTransformMakeScale(0.0001, 0.0001);
} completion:^(BOOL finished) {
[_tableView removeFromSuperview];
[self removeFromSuperview];
if (self.hideHandle) {
self.hideHandle();
}
}];
}
#pragma mark - Draw triangle
- (void)drawRect:(CGRect)rect {
// 設(shè)置背景色
[[UIColor whiteColor] set];
//拿到當(dāng)前視圖準備好的畫板
CGContextRef context = UIGraphicsGetCurrentContext();
//利用path進行繪制三角形
CGContextBeginPath(context);
CGPoint point = _trianglePoint;
// 設(shè)置起點
CGContextMoveToPoint(context, point.x, point.y);
// 畫線
CGContextAddLineToPoint(context, point.x - 10, point.y + 10);
CGContextAddLineToPoint(context, point.x + 10, point.y + 10);
CGContextClosePath(context);
// 設(shè)置填充色
[[UIColor whiteColor] setFill];
// 設(shè)置邊框顏色
[[UIColor whiteColor] setStroke];
// 繪制路徑
CGContextDrawPath(context, kCGPathFillStroke);
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.tableData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PopMenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PopMenuTableViewCell" forIndexPath:indexPath];
NSDictionary *dic = _tableData[indexPath.row];
cell.leftImageView.image = [UIImage imageNamed:dic[@"imageName"]];
cell.titleLabel.text = dic[@"title"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.layoutMargins = UIEdgeInsetsZero;
cell.separatorInset = UIEdgeInsetsZero;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self hide];
if (_action) {
_action(indexPath.row);
}
}
@end
調(diào)用
[QQPopMenuView showWithItems:@[@{@"title":@"發(fā)起討論",@"imageName":@"popMenu_createChat"},
@{@"title":@"掃描名片",@"imageName":@"popMenu_scanCard"},
@{@"title":@"寫日報",@"imageName":@"popMenu_writeReport"},
@{@"title":@"外勤簽到",@"imageName":@"popMenu_signIn"}]
width:130
triangleLocation:CGPointMake([UIScreen mainScreen].bounds.size.width-30, 64+5)
action:^(NSInteger index) {
NSLog(@"點擊了第%ld行",index);
}];
效果圖
screenshot.gif