需求如下:
点击右导航按钮弹出列表菜单,点击菜单中的任意事件,跳转或者响应不同事件。
具体实现
@interface SCPopListView : UIView
@property (nonatomic, strong) UIColor* thumbColor;
@property (nonatomic, strong) UIColor* textColor;
@property (nonatomic, assign) CGFloat maxWidth;
@property (nonatomic, assign) CGFloat bottomSacping;
@property (nonatomic, assign) UITableViewCellSelectionStyle cellSelectionStyle;
@property (nonatomic, assign) BOOL isCornerRadius;
@property (nonatomic, strong) NSArray *rightViewArr;
@property (nonatomic, strong) NSArray *titleArr;
@property (nonatomic, strong) NSArray *imgArr;
@property (nonatomic, strong) NSArray *placeholderArr;
@property (nonatomic, copy) void (^selectBlock)(NSInteger index);
@end
@interface SCPopOverListView : UIView
@property (nonatomic, strong) SCPopListView *listView;
- (id)initWithTitles:(NSArray*)titleArr images:(NSArray*)imgArr superView:(UIView*)superView maxWidth:(CGFloat)maxWidth andisCornerRadius:(BOOL)isCornerRadius;
- (void)showPopList;
- (void)hidePopList;
@end
.m实现部分
@interface SCPopListView ()<UITableViewDataSource, UITableViewDelegate>
{
NSInteger _rowNum;
UIView *thumb;
}
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation SCPopListView
- (void)setBackgroundColor:(UIColor *)backgroundColor{
[super setBackgroundColor:backgroundColor];
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_thumbColor = [UIColor whiteColor];//这个是那个小三角
_textColor = [UIColor SCTextBlackColor];
_bottomSacping = 0;
_cellSelectionStyle = UITableViewCellSelectionStyleDefault;
//创建一个三角形
thumb = [[UIView alloc] initWithFrame:CGRectMake(frame.size.width - 20, 0, 10, 5)];
thumb.backgroundColor = _thumbColor;
[self addSubview:thumb];
UIBezierPath *path = [UIBezierPath bezierPath];
//设置初始线段的起点
[path moveToPoint:CGPointMake(0, thumb.height)];
[path addLineToPoint:CGPointMake(thumb.width / 2.0f, 0)];
[path addLineToPoint:CGPointMake(thumb.width, thumb.height)];
[path closePath];
CAShapeLayer *shape = [[CAShapeLayer alloc] init];
[shape setPath:path.CGPath];
thumb.layer.mask = shape;
//背景图片
UIImageView *backImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
backImage.autoresizingMask = UIViewAutoresizingFlexibleHeight;
backImage.image = [[UIImage imageNamed:@"fmp_toppop_background"] stretchableImageWithLeftCapWidth:20 topCapHeight:30];
[self addSubview:backImage];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(25, 8, frame.size.width - 50, frame.size.height - 5) style:UITableViewStylePlain];
_tableView.backgroundColor = [UIColor clearColor];
_tableView.layer.cornerRadius = 2;
_tableView.layer.masksToBounds = YES;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.scrollEnabled = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
[self addSubview:_tableView];
}
return self;
}
//设置三角的颜色
- (void)setThumbColor:(UIColor *)thumbColor{
_thumbColor = thumbColor;
thumb.backgroundColor = _thumbColor;
// _tableView.backgroundColor = _thumbColor;
}
- (void)setTextColor:(UIColor *)textColor{
_textColor = textColor;
[_tableView reloadData];
}
- (void)setRightViewArr:(NSArray *)rightViewArr{
_rightViewArr = rightViewArr;
[_tableView reloadData];
}
- (void)setTitleArr:(NSArray *)titleArr {
_titleArr = titleArr;
[self updateHieght];
}
- (void)setImgArr:(NSArray *)imgArr {
_imgArr = imgArr;
[self updateHieght];
}
- (void)setPlaceholderArr:(NSArray *)placeholderArr{
_placeholderArr = placeholderArr;
[_tableView reloadData];
}
- (void)setBottomSacping:(CGFloat)bottomSacping{
_bottomSacping = bottomSacping;
[self updateHieght];
}
- (void)setCellSelectionStyle:(UITableViewCellSelectionStyle)cellSelectionStyle{
_cellSelectionStyle = cellSelectionStyle;
[self.tableView reloadData];
}
- (void)updateHieght {
_rowNum = self.titleArr.count > self.imgArr.count ? self.titleArr.count : self.imgArr.count;
self.tableView.height = self.height = _rowNum * 44 + _bottomSacping;
[self.tableView reloadData];
}
#pragma mark UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _rowNum;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 40;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"UITableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, (44-15)/2, 15, 15)];
imgView.tag = 100;
[cell.contentView addSubview:imgView];
if (_isCornerRadius) {
imgView.layer.cornerRadius = imgView.frame.size.width/2;
imgView.clipsToBounds = YES;
}
UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(imgView.right + 10, (44-20)/2, cell.width - imgView.right - 10, 20)];
lab.backgroundColor = [UIColor clearColor];
lab.autoresizingMask = UIViewAutoresizingFlexibleWidth;
lab.textColor = _textColor;
lab.font = [UIFont systemFontOfSize:12];
lab.tag = 101;
[cell.contentView addSubview:lab];
}
//显示列表的线
[cell.contentView showTopSeparateLine:indexPath.row != 0 edgeInset:UIEdgeInsetsZero];
UIImageView *imgView = [cell viewWithTag:100];
UILabel *lab = [cell viewWithTag:101];
id image = self.imgArr.count > indexPath.row ? self.imgArr[indexPath.row] : nil;
if ([image isKindOfClass:[UIImage class]]) {
imgView.image = image;
}else if ([image isKindOfClass:[NSString class]]){
// [imgView sd_setImageWithURL:[NSURL URLWithString:image] placeholderImage:[UIImage imageNamed:self.placeholderArr.count > indexPath.row ? self.placeholderArr[indexPath.row] : nil] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// if (image) {
// return ;
// }
// imgView.contentMode = UIViewContentModeScaleToFill;
// }];
}
lab.text = self.titleArr.count > indexPath.row ? self.titleArr[indexPath.row] : @"";
cell.selectionStyle = _cellSelectionStyle;
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (self.selectBlock)
self.selectBlock(indexPath.row);
}
@end
@interface SCPopOverListView ()<UIGestureRecognizerDelegate>
{
UIView *_superView;
}
@end
@implementation SCPopOverListView
- (id)initWithTitles:(NSArray*)titleArr images:(NSArray*)imgArr superView:(UIView*)superView maxWidth:(CGFloat)maxWidth andisCornerRadius:(BOOL)isCornerRadius{
self = [super initWithFrame:superView.bounds];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_superView = superView;
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hidePopList)];
gesture.delegate = self;
[self addGestureRecognizer:gesture];
_listView = [[SCPopListView alloc] initWithFrame:CGRectMake(self.width - maxWidth , 66, maxWidth, 20)];
_listView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
_listView.titleArr = titleArr;
_listView.imgArr = imgArr;
_listView.isCornerRadius = isCornerRadius;
[self addSubview:_listView];
}
return self;
}
- (void)showPopList {
[_superView addSubview:self];
}
- (void)hidePopList {
[self removeFromSuperview];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
@end
知识点
- 那个三角形是如何画出来的呢?
绘制多边形,实际上就是又一些直线条连成,主要使用moveToPoint: 和addLineToPoint:
方法去创建,moveToPoint:这个方法是设置起始点,意味着从这个点开始,我们就可以使
用addLineToPoint:去设置我们想要创建的多边形经过的点,也就是两线相交的那个点,用
addLineToPoint:去创建一个形状的线段,我们可以连续创建line,每一个line的起点都是
先前的终点,终点就是指定的点,将线段连接起来就是我们想要创建的多边形了。
在这里我们可以看到最后第3条线是用[path closePath];得到的,closePath方法不仅结
束一个shape的subpath表述,它也在最后一个点和第一个点之间画一条线段,这个一个便
利的方法我们不需要去画最后一条线了.
- 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 若为UITableViewCellContentView(即点击了tableViewCell),则不截获Touch事件
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
具体使用
- (SCPopOverListView*)popListView {
if (!_popListView) {
NSArray *titleArr = @[@"编辑", @"删除"];
NSArray *imgArr = @[[UIImage imageNamed:@"fmp_edit"], [UIImage imageNamed:@"fmp_delete"]];
_popListView = [[SCPopOverListView alloc] initWithTitles:titleArr images:imgArr superView:self.navigationController.view maxWidth:120 andisCornerRadius:NO];
_popListView.listView.bottomSacping = 10;
__weak typeof(self) weakSelf = self;
__weak SCPopOverListView *weakPop = _popListView;
_popListView.listView.selectBlock = ^(NSInteger index) {
if (index == 0) {
[weakPop hidePopList];
};
}
return _popListView;
}