819 lines
27 KiB
Mathematica
819 lines
27 KiB
Mathematica
|
|
//
|
||
|
|
// YBPopupMenu.m
|
||
|
|
// YBPopupMenu
|
||
|
|
//
|
||
|
|
// Created by lyb on 2017/5/10.
|
||
|
|
// Copyright © 2017年 lyb. All rights reserved.
|
||
|
|
//
|
||
|
|
|
||
|
|
#import "YBPopupMenu.h"
|
||
|
|
#import "YBPopupMenuPath.h"
|
||
|
|
|
||
|
|
#define YBScreenWidth [UIScreen mainScreen].bounds.size.width
|
||
|
|
#define YBScreenHeight [UIScreen mainScreen].bounds.size.height
|
||
|
|
#define YBMainWindow [UIApplication sharedApplication].keyWindow
|
||
|
|
#define YB_SAFE_BLOCK(BlockName, ...) ({ !BlockName ? nil : BlockName(__VA_ARGS__); })
|
||
|
|
|
||
|
|
#pragma mark - /////////////
|
||
|
|
#pragma mark - private cell
|
||
|
|
|
||
|
|
@interface YBPopupMenuCell : UITableViewCell
|
||
|
|
@property (nonatomic, assign) BOOL isShowSeparator;
|
||
|
|
@property (nonatomic, strong) UIColor * separatorColor;
|
||
|
|
|
||
|
|
@property (nonatomic, strong) UILabel *titleLabel;
|
||
|
|
|
||
|
|
// 分割线
|
||
|
|
@property (nonatomic, strong) UIView *lineView;
|
||
|
|
|
||
|
|
@property (nonatomic, assign) BOOL checked;
|
||
|
|
@property (nonatomic, strong) UIImageView *checkedIconView;
|
||
|
|
|
||
|
|
@end
|
||
|
|
|
||
|
|
@implementation YBPopupMenuCell
|
||
|
|
|
||
|
|
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||
|
|
{
|
||
|
|
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||
|
|
if (self) {
|
||
|
|
_isShowSeparator = YES;
|
||
|
|
_separatorColor = [UIColor clearColor];
|
||
|
|
|
||
|
|
UILabel *titleLabel = [[UILabel alloc] init];
|
||
|
|
titleLabel.font = [UIFont systemFontOfSize:16];
|
||
|
|
titleLabel.backgroundColor = [UIColor clearColor];
|
||
|
|
titleLabel.textAlignment = NSTextAlignmentCenter;
|
||
|
|
self.titleLabel = titleLabel;
|
||
|
|
[self addSubview:titleLabel];
|
||
|
|
|
||
|
|
UIView *lineView = [[UIView alloc] init];
|
||
|
|
lineView.backgroundColor = COLOR_WITH_RGB(0xDEDEDE);
|
||
|
|
lineView.height = 1.0;
|
||
|
|
self.lineView = lineView;
|
||
|
|
[self addSubview:lineView];
|
||
|
|
|
||
|
|
self.checkedIconView = [[UIImageView alloc]init];
|
||
|
|
[self addSubview:self.checkedIconView];
|
||
|
|
|
||
|
|
|
||
|
|
[self setNeedsDisplay];
|
||
|
|
}
|
||
|
|
return self;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
- (void)setChecked:(BOOL)checked
|
||
|
|
{
|
||
|
|
_checked = checked;
|
||
|
|
self.checkedIconView.hidden = !checked;
|
||
|
|
[self setNeedsLayout];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)layoutSubviews
|
||
|
|
{
|
||
|
|
[super layoutSubviews];
|
||
|
|
CGFloat margin = 10;
|
||
|
|
self.titleLabel.frame = CGRectMake(margin, 0, self.width - margin * 2, self.height);
|
||
|
|
|
||
|
|
self.checkedIconView.height = FIX_SIZE(12);
|
||
|
|
UIImage *image = self.checkedIconView.image;
|
||
|
|
if (image) {
|
||
|
|
self.checkedIconView.width = image.size.width / image.size.height * self.checkedIconView.height;
|
||
|
|
} else{
|
||
|
|
self.checkedIconView.frame = CGRectZero;
|
||
|
|
}
|
||
|
|
|
||
|
|
self.checkedIconView.centerY = self.titleLabel.centerY;
|
||
|
|
self.checkedIconView.right = self.width - margin;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setIsShowSeparator:(BOOL)isShowSeparator
|
||
|
|
{
|
||
|
|
_isShowSeparator = isShowSeparator;
|
||
|
|
[self setNeedsDisplay];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setSeparatorColor:(UIColor *)separatorColor
|
||
|
|
{
|
||
|
|
_separatorColor = separatorColor;
|
||
|
|
[self setNeedsDisplay];
|
||
|
|
}
|
||
|
|
|
||
|
|
//- (void)drawRect:(CGRect)rect
|
||
|
|
//{
|
||
|
|
// if (!_isShowSeparator) return;
|
||
|
|
// UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, rect.size.height - 0.5, rect.size.width, 0.5)];
|
||
|
|
//// [_separatorColor setFill];
|
||
|
|
// [bezierPath fillWithBlendMode:kCGBlendModeNormal alpha:1];
|
||
|
|
// [bezierPath closePath];
|
||
|
|
//}
|
||
|
|
|
||
|
|
@end
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
@interface YBPopupMenu ()
|
||
|
|
<
|
||
|
|
UITableViewDelegate,
|
||
|
|
UITableViewDataSource
|
||
|
|
>
|
||
|
|
|
||
|
|
@property (nonatomic, strong) UIView * menuBackView;
|
||
|
|
@property (nonatomic) CGRect relyRect;
|
||
|
|
@property (nonatomic, assign) CGFloat itemWidth;
|
||
|
|
@property (nonatomic) CGPoint point;
|
||
|
|
@property (nonatomic, assign) BOOL isCornerChanged;
|
||
|
|
@property (nonatomic, strong) UIColor * separatorColor;
|
||
|
|
@property (nonatomic, assign) BOOL isChangeDirection;
|
||
|
|
@end
|
||
|
|
|
||
|
|
@implementation YBPopupMenu
|
||
|
|
|
||
|
|
- (instancetype)init
|
||
|
|
{
|
||
|
|
self = [super init];
|
||
|
|
if (self) {
|
||
|
|
[self setDefaultSettings];
|
||
|
|
}
|
||
|
|
return self;
|
||
|
|
}
|
||
|
|
|
||
|
|
#pragma mark - publics
|
||
|
|
+ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id<YBPopupMenuDelegate>)delegate
|
||
|
|
{
|
||
|
|
YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init];
|
||
|
|
popupMenu.point = point;
|
||
|
|
popupMenu.titles = titles;
|
||
|
|
popupMenu.images = icons;
|
||
|
|
popupMenu.itemWidth = itemWidth;
|
||
|
|
popupMenu.delegate = delegate;
|
||
|
|
[popupMenu show];
|
||
|
|
return popupMenu;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id<YBPopupMenuDelegate>)delegate
|
||
|
|
{
|
||
|
|
CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow];
|
||
|
|
CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height);
|
||
|
|
YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init];
|
||
|
|
popupMenu.point = relyPoint;
|
||
|
|
popupMenu.relyRect = absoluteRect;
|
||
|
|
popupMenu.titles = titles;
|
||
|
|
popupMenu.images = icons;
|
||
|
|
popupMenu.itemWidth = itemWidth;
|
||
|
|
popupMenu.delegate = delegate;
|
||
|
|
[popupMenu show];
|
||
|
|
return popupMenu;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting
|
||
|
|
{
|
||
|
|
YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init];
|
||
|
|
popupMenu.point = point;
|
||
|
|
popupMenu.titles = titles;
|
||
|
|
popupMenu.images = icons;
|
||
|
|
popupMenu.itemWidth = itemWidth;
|
||
|
|
YB_SAFE_BLOCK(otherSetting,popupMenu);
|
||
|
|
[popupMenu show];
|
||
|
|
return popupMenu;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting
|
||
|
|
{
|
||
|
|
CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow];
|
||
|
|
CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height);
|
||
|
|
YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init];
|
||
|
|
popupMenu.point = relyPoint;
|
||
|
|
popupMenu.relyRect = absoluteRect;
|
||
|
|
popupMenu.titles = titles;
|
||
|
|
popupMenu.images = icons;
|
||
|
|
popupMenu.itemWidth = itemWidth;
|
||
|
|
YB_SAFE_BLOCK(otherSetting,popupMenu);
|
||
|
|
[popupMenu show];
|
||
|
|
return popupMenu;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)dismiss
|
||
|
|
{
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganDismiss)]) {
|
||
|
|
[self.delegate ybPopupMenuBeganDismiss];
|
||
|
|
}
|
||
|
|
[UIView animateWithDuration: 0.25 animations:^{
|
||
|
|
self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1);
|
||
|
|
self.alpha = 0;
|
||
|
|
_menuBackView.alpha = 0;
|
||
|
|
} completion:^(BOOL finished) {
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidDismiss)]) {
|
||
|
|
[self.delegate ybPopupMenuDidDismiss];
|
||
|
|
}
|
||
|
|
self.delegate = nil;
|
||
|
|
[self removeFromSuperview];
|
||
|
|
[_menuBackView removeFromSuperview];
|
||
|
|
}];
|
||
|
|
}
|
||
|
|
|
||
|
|
#pragma mark tableViewDelegate & dataSource
|
||
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||
|
|
{
|
||
|
|
return _titles.count;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||
|
|
{
|
||
|
|
UITableViewCell * tableViewCell = nil;
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:cellForRowAtIndex:)]) {
|
||
|
|
tableViewCell = [self.delegate ybPopupMenu:self cellForRowAtIndex:indexPath.row];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (tableViewCell) {
|
||
|
|
return tableViewCell;
|
||
|
|
}
|
||
|
|
|
||
|
|
static NSString * identifier = @"ybPopupMenu";
|
||
|
|
YBPopupMenuCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
|
||
|
|
if (!cell) {
|
||
|
|
cell = [[YBPopupMenuCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
|
||
|
|
cell.titleLabel.numberOfLines = 0;
|
||
|
|
}
|
||
|
|
cell.backgroundColor = [UIColor clearColor];
|
||
|
|
|
||
|
|
cell.checked = indexPath.row == _checkedRow;
|
||
|
|
|
||
|
|
cell.titleLabel.textColor = cell.checked ? _checkedTextColor : _textColor;
|
||
|
|
cell.checkedIconView.image = cell.checked ? _checkedIconImage : nil;
|
||
|
|
|
||
|
|
cell.titleLabel.font = cell.checked ? _checkedTextFont : _textFont ?: [UIFont systemFontOfSize:_fontSize];
|
||
|
|
// cell.titleLabel.backgroundColor = [UIColor redColor];
|
||
|
|
cell.lineView.frame = CGRectMake(self.lineInset.left, _itemHeight - cell.lineView.height - self.lineInset.bottom, _itemWidth - self.lineInset.left - self.lineInset.right, _lineHeight);
|
||
|
|
cell.lineView.backgroundColor = _lineColor;
|
||
|
|
if ([_titles[indexPath.row] isKindOfClass:[NSAttributedString class]]) {
|
||
|
|
cell.titleLabel.attributedText = _titles[indexPath.row];
|
||
|
|
}else if ([_titles[indexPath.row] isKindOfClass:[NSString class]]) {
|
||
|
|
cell.titleLabel.text = _titles[indexPath.row];
|
||
|
|
}else {
|
||
|
|
cell.titleLabel.text = nil;
|
||
|
|
}
|
||
|
|
// cell.separatorColor = _separatorColor;
|
||
|
|
if (_images.count >= indexPath.row + 1) {
|
||
|
|
if ([_images[indexPath.row] isKindOfClass:[NSString class]]) {
|
||
|
|
cell.imageView.image = [UIImage imageNamed:_images[indexPath.row]];
|
||
|
|
}else if ([_images[indexPath.row] isKindOfClass:[UIImage class]]){
|
||
|
|
cell.imageView.image = _images[indexPath.row];
|
||
|
|
}else {
|
||
|
|
cell.imageView.image = nil;
|
||
|
|
}
|
||
|
|
}else {
|
||
|
|
cell.imageView.image = nil;
|
||
|
|
}
|
||
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||
|
|
|
||
|
|
return cell;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||
|
|
{
|
||
|
|
return _itemHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||
|
|
{
|
||
|
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||
|
|
if (_dismissOnSelected) [self dismiss];
|
||
|
|
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidSelectedAtIndex:ybPopupMenu:)]) {
|
||
|
|
|
||
|
|
[self.delegate ybPopupMenuDidSelectedAtIndex:indexPath.row ybPopupMenu:self];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:didSelectedAtIndex:)]) {
|
||
|
|
[self.delegate ybPopupMenu:self didSelectedAtIndex:indexPath.row];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#pragma mark - scrollViewDelegate
|
||
|
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||
|
|
{
|
||
|
|
if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) {
|
||
|
|
YBPopupMenuCell *cell = [self getLastVisibleCell];
|
||
|
|
cell.isShowSeparator = YES;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
|
||
|
|
{
|
||
|
|
if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) {
|
||
|
|
YBPopupMenuCell *cell = [self getLastVisibleCell];
|
||
|
|
cell.isShowSeparator = NO;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- (YBPopupMenuCell *)getLastVisibleCell
|
||
|
|
{
|
||
|
|
NSArray <NSIndexPath *>*indexPaths = [self.tableView indexPathsForVisibleRows];
|
||
|
|
indexPaths = [indexPaths sortedArrayUsingComparator:^NSComparisonResult(NSIndexPath * _Nonnull obj1, NSIndexPath * _Nonnull obj2) {
|
||
|
|
return obj1.row < obj2.row;
|
||
|
|
}];
|
||
|
|
NSIndexPath *indexPath = indexPaths.firstObject;
|
||
|
|
return [self.tableView cellForRowAtIndexPath:indexPath];
|
||
|
|
}
|
||
|
|
|
||
|
|
#pragma mark - privates
|
||
|
|
- (void)show
|
||
|
|
{
|
||
|
|
[YBMainWindow addSubview:_menuBackView];
|
||
|
|
[YBMainWindow addSubview:self];
|
||
|
|
if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) {
|
||
|
|
YBPopupMenuCell *cell = [self getLastVisibleCell];
|
||
|
|
cell.isShowSeparator = NO;
|
||
|
|
}
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganShow)]) {
|
||
|
|
[self.delegate ybPopupMenuBeganShow];
|
||
|
|
}
|
||
|
|
self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1);
|
||
|
|
[UIView animateWithDuration: 0.25 animations:^{
|
||
|
|
self.layer.affineTransform = CGAffineTransformMakeScale(1.0, 1.0);
|
||
|
|
self.alpha = 1;
|
||
|
|
_menuBackView.alpha = 1;
|
||
|
|
} completion:^(BOOL finished) {
|
||
|
|
if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidShow)]) {
|
||
|
|
[self.delegate ybPopupMenuDidShow];
|
||
|
|
}
|
||
|
|
}];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setDefaultSettings
|
||
|
|
{
|
||
|
|
_cornerRadius = 10.0;
|
||
|
|
_rectCorner = UIRectCornerAllCorners;
|
||
|
|
self.isShowShadow = YES;
|
||
|
|
_dismissOnSelected = YES;
|
||
|
|
_dismissOnTouchOutside = YES;
|
||
|
|
_fontSize = 15;
|
||
|
|
_textColor = [UIColor blackColor];
|
||
|
|
_checkedTextColor = _textColor;
|
||
|
|
_lineHeight = 1.0;
|
||
|
|
_offset = 0.0;
|
||
|
|
_lineColor = [UIColor darkGrayColor];
|
||
|
|
_relyRect = CGRectZero;
|
||
|
|
_point = CGPointZero;
|
||
|
|
_borderWidth = 0.0;
|
||
|
|
_borderColor = [UIColor lightGrayColor];
|
||
|
|
_arrowWidth = 15.0;
|
||
|
|
_arrowHeight = 10.0;
|
||
|
|
_backColor = [UIColor whiteColor];
|
||
|
|
_type = YBPopupMenuTypeDefault;
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionTop;
|
||
|
|
_priorityDirection = YBPopupMenuPriorityDirectionTop;
|
||
|
|
_minSpace = 10.0;
|
||
|
|
_maxVisibleCount = 5;
|
||
|
|
_itemHeight = 44;
|
||
|
|
_isCornerChanged = NO;
|
||
|
|
_showMaskView = YES;
|
||
|
|
_menuBackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, YBScreenWidth, YBScreenHeight)];
|
||
|
|
_menuBackView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
||
|
|
_menuBackView.alpha = 0;
|
||
|
|
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(touchOutSide)];
|
||
|
|
[_menuBackView addGestureRecognizer: tap];
|
||
|
|
self.alpha = 0;
|
||
|
|
self.backgroundColor = [UIColor clearColor];
|
||
|
|
[self addSubview:self.tableView];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (UITableView *)tableView
|
||
|
|
{
|
||
|
|
if (!_tableView) {
|
||
|
|
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||
|
|
_tableView.backgroundColor = [UIColor clearColor];
|
||
|
|
_tableView.tableFooterView = [UIView new];
|
||
|
|
_tableView.delegate = self;
|
||
|
|
_tableView.dataSource = self;
|
||
|
|
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||
|
|
|
||
|
|
}
|
||
|
|
return _tableView;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)touchOutSide
|
||
|
|
{
|
||
|
|
if (_dismissOnTouchOutside) {
|
||
|
|
[self dismiss];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setIsShowShadow:(BOOL)isShowShadow
|
||
|
|
{
|
||
|
|
_isShowShadow = isShowShadow;
|
||
|
|
self.layer.shadowOpacity = isShowShadow ? 0.5 : 0;
|
||
|
|
self.layer.shadowOffset = CGSizeMake(0, 0);
|
||
|
|
self.layer.shadowRadius = isShowShadow ? 2.0 : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setShowMaskView:(BOOL)showMaskView
|
||
|
|
{
|
||
|
|
_showMaskView = showMaskView;
|
||
|
|
_menuBackView.backgroundColor = showMaskView ? [[UIColor blackColor] colorWithAlphaComponent:0.5] : [UIColor clearColor];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setType:(YBPopupMenuType)type
|
||
|
|
{
|
||
|
|
_type = type;
|
||
|
|
switch (type) {
|
||
|
|
case YBPopupMenuTypeDark:
|
||
|
|
{
|
||
|
|
_textColor = [UIColor lightGrayColor];
|
||
|
|
_backColor = [UIColor colorWithRed:0.25 green:0.27 blue:0.29 alpha:1];
|
||
|
|
_separatorColor = [UIColor clearColor];
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
{
|
||
|
|
_textColor = [UIColor blackColor];
|
||
|
|
_backColor = [UIColor whiteColor];
|
||
|
|
_separatorColor = [UIColor clearColor];
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setFontSize:(CGFloat)fontSize
|
||
|
|
{
|
||
|
|
_fontSize = fontSize;
|
||
|
|
[self.tableView reloadData];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setTextColor:(UIColor *)textColor
|
||
|
|
{
|
||
|
|
_textColor = textColor;
|
||
|
|
[self.tableView reloadData];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setPoint:(CGPoint)point
|
||
|
|
{
|
||
|
|
_point = point;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setItemWidth:(CGFloat)itemWidth
|
||
|
|
{
|
||
|
|
_itemWidth = itemWidth;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setItemHeight:(CGFloat)itemHeight
|
||
|
|
{
|
||
|
|
_itemHeight = itemHeight;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setBorderWidth:(CGFloat)borderWidth
|
||
|
|
{
|
||
|
|
_borderWidth = borderWidth;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setBorderColor:(UIColor *)borderColor
|
||
|
|
{
|
||
|
|
_borderColor = borderColor;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setArrowPosition:(CGFloat)arrowPosition
|
||
|
|
{
|
||
|
|
_arrowPosition = arrowPosition;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setArrowWidth:(CGFloat)arrowWidth
|
||
|
|
{
|
||
|
|
_arrowWidth = arrowWidth;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setArrowHeight:(CGFloat)arrowHeight
|
||
|
|
{
|
||
|
|
_arrowHeight = arrowHeight;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setArrowDirection:(YBPopupMenuArrowDirection)arrowDirection
|
||
|
|
{
|
||
|
|
_arrowDirection = arrowDirection;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setMaxVisibleCount:(NSInteger)maxVisibleCount
|
||
|
|
{
|
||
|
|
_maxVisibleCount = maxVisibleCount;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setBackColor:(UIColor *)backColor
|
||
|
|
{
|
||
|
|
_backColor = backColor;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setTitles:(NSArray *)titles
|
||
|
|
{
|
||
|
|
_titles = titles;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setImages:(NSArray *)images
|
||
|
|
{
|
||
|
|
_images = images;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setPriorityDirection:(YBPopupMenuPriorityDirection)priorityDirection
|
||
|
|
{
|
||
|
|
_priorityDirection = priorityDirection;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setRectCorner:(UIRectCorner)rectCorner
|
||
|
|
{
|
||
|
|
_rectCorner = rectCorner;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setCornerRadius:(CGFloat)cornerRadius
|
||
|
|
{
|
||
|
|
_cornerRadius = cornerRadius;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setOffset:(CGFloat)offset
|
||
|
|
{
|
||
|
|
_offset = offset;
|
||
|
|
[self updateUI];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)updateUI
|
||
|
|
{
|
||
|
|
CGFloat height;
|
||
|
|
if (_titles.count > _maxVisibleCount) {
|
||
|
|
height = _itemHeight * _maxVisibleCount + _borderWidth * 2;
|
||
|
|
self.tableView.bounces = YES;
|
||
|
|
}else {
|
||
|
|
height = _itemHeight * _titles.count + _borderWidth * 2;
|
||
|
|
self.tableView.bounces = NO;
|
||
|
|
}
|
||
|
|
_isChangeDirection = NO;
|
||
|
|
if (_priorityDirection == YBPopupMenuPriorityDirectionTop) {
|
||
|
|
if (_point.y + height + _arrowHeight > YBScreenHeight - _minSpace) {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionBottom;
|
||
|
|
_isChangeDirection = YES;
|
||
|
|
}else {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionTop;
|
||
|
|
_isChangeDirection = NO;
|
||
|
|
}
|
||
|
|
}else if (_priorityDirection == YBPopupMenuPriorityDirectionBottom) {
|
||
|
|
if (_point.y - height - _arrowHeight < _minSpace) {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionTop;
|
||
|
|
_isChangeDirection = YES;
|
||
|
|
}else {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionBottom;
|
||
|
|
_isChangeDirection = NO;
|
||
|
|
}
|
||
|
|
}else if (_priorityDirection == YBPopupMenuPriorityDirectionLeft) {
|
||
|
|
if (_point.x + _itemWidth + _arrowHeight > YBScreenWidth - _minSpace) {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionRight;
|
||
|
|
_isChangeDirection = YES;
|
||
|
|
}else {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionLeft;
|
||
|
|
_isChangeDirection = NO;
|
||
|
|
}
|
||
|
|
}else if (_priorityDirection == YBPopupMenuPriorityDirectionRight) {
|
||
|
|
if (_point.x - _itemWidth - _arrowHeight < _minSpace) {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionLeft;
|
||
|
|
_isChangeDirection = YES;
|
||
|
|
}else {
|
||
|
|
_arrowDirection = YBPopupMenuArrowDirectionRight;
|
||
|
|
_isChangeDirection = NO;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
[self setArrowPosition];
|
||
|
|
[self setRelyRect];
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop) {
|
||
|
|
CGFloat y = _isChangeDirection ? _point.y : _point.y;
|
||
|
|
if (_arrowPosition > _itemWidth / 2) {
|
||
|
|
self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}else if (_arrowPosition < _itemWidth / 2) {
|
||
|
|
self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}else {
|
||
|
|
self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
CGFloat y = _isChangeDirection ? _point.y - _arrowHeight - height : _point.y - _arrowHeight - height;
|
||
|
|
if (_arrowPosition > _itemWidth / 2) {
|
||
|
|
self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}else if (_arrowPosition < _itemWidth / 2) {
|
||
|
|
self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}else {
|
||
|
|
self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight);
|
||
|
|
}
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) {
|
||
|
|
CGFloat x = _isChangeDirection ? _point.x : _point.x;
|
||
|
|
if (_arrowPosition < _itemHeight / 2) {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}else if (_arrowPosition > _itemHeight / 2) {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}else {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
CGFloat x = _isChangeDirection ? _point.x - _itemWidth - _arrowHeight : _point.x - _itemWidth - _arrowHeight;
|
||
|
|
if (_arrowPosition < _itemHeight / 2) {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}else if (_arrowPosition > _itemHeight / 2) {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}else {
|
||
|
|
self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height);
|
||
|
|
}
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionNone) {
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_isChangeDirection) {
|
||
|
|
[self changeRectCorner];
|
||
|
|
}
|
||
|
|
[self setAnchorPoint];
|
||
|
|
[self setOffset];
|
||
|
|
[self.tableView reloadData];
|
||
|
|
[self setNeedsDisplay];
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setRelyRect
|
||
|
|
{
|
||
|
|
if (CGRectEqualToRect(_relyRect, CGRectZero)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop) {
|
||
|
|
_point.y = _relyRect.size.height + _relyRect.origin.y;
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
_point.y = _relyRect.origin.y;
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) {
|
||
|
|
_point = CGPointMake(_relyRect.origin.x + _relyRect.size.width, _relyRect.origin.y + _relyRect.size.height / 2);
|
||
|
|
}else {
|
||
|
|
_point = CGPointMake(_relyRect.origin.x, _relyRect.origin.y + _relyRect.size.height / 2);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
- (void)setFrame:(CGRect)frame
|
||
|
|
{
|
||
|
|
[super setFrame:frame];
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop) {
|
||
|
|
self.tableView.frame = CGRectMake(_borderWidth, _borderWidth + _arrowHeight, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
self.tableView.frame = CGRectMake(_borderWidth, _borderWidth, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) {
|
||
|
|
self.tableView.frame = CGRectMake(_borderWidth + _arrowHeight, _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
self.tableView.frame = CGRectMake(_borderWidth , _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)changeRectCorner
|
||
|
|
{
|
||
|
|
if (_isCornerChanged || _rectCorner == UIRectCornerAllCorners) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
BOOL haveTopLeftCorner = NO, haveTopRightCorner = NO, haveBottomLeftCorner = NO, haveBottomRightCorner = NO;
|
||
|
|
if (_rectCorner & UIRectCornerTopLeft) {
|
||
|
|
haveTopLeftCorner = YES;
|
||
|
|
}
|
||
|
|
if (_rectCorner & UIRectCornerTopRight) {
|
||
|
|
haveTopRightCorner = YES;
|
||
|
|
}
|
||
|
|
if (_rectCorner & UIRectCornerBottomLeft) {
|
||
|
|
haveBottomLeftCorner = YES;
|
||
|
|
}
|
||
|
|
if (_rectCorner & UIRectCornerBottomRight) {
|
||
|
|
haveBottomRightCorner = YES;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
|
||
|
|
if (haveTopLeftCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerBottomLeft;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerBottomLeft);
|
||
|
|
}
|
||
|
|
if (haveTopRightCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerBottomRight;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerBottomRight);
|
||
|
|
}
|
||
|
|
if (haveBottomLeftCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerTopLeft;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerTopLeft);
|
||
|
|
}
|
||
|
|
if (haveBottomRightCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerTopRight;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerTopRight);
|
||
|
|
}
|
||
|
|
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
if (haveTopLeftCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerTopRight;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerTopRight);
|
||
|
|
}
|
||
|
|
if (haveTopRightCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerTopLeft;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerTopLeft);
|
||
|
|
}
|
||
|
|
if (haveBottomLeftCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerBottomRight;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerBottomRight);
|
||
|
|
}
|
||
|
|
if (haveBottomRightCorner) {
|
||
|
|
_rectCorner = _rectCorner | UIRectCornerBottomLeft;
|
||
|
|
}else {
|
||
|
|
_rectCorner = _rectCorner & (~UIRectCornerBottomLeft);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
_isCornerChanged = YES;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setOffset
|
||
|
|
{
|
||
|
|
if (_itemWidth == 0) return;
|
||
|
|
|
||
|
|
CGRect originRect = self.frame;
|
||
|
|
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop) {
|
||
|
|
originRect.origin.y += _offset;
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
originRect.origin.y -= _offset;
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) {
|
||
|
|
originRect.origin.x += _offset;
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
originRect.origin.x -= _offset;
|
||
|
|
}
|
||
|
|
self.frame = originRect;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setAnchorPoint
|
||
|
|
{
|
||
|
|
if (_itemWidth == 0) return;
|
||
|
|
|
||
|
|
CGPoint point = CGPointMake(0.5, 0.5);
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop) {
|
||
|
|
point = CGPointMake(_arrowPosition / _itemWidth, 0);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
point = CGPointMake(_arrowPosition / _itemWidth, 1);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) {
|
||
|
|
point = CGPointMake(0, (_itemHeight - _arrowPosition) / _itemHeight);
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
point = CGPointMake(1, (_itemHeight - _arrowPosition) / _itemHeight);
|
||
|
|
}
|
||
|
|
CGRect originRect = self.frame;
|
||
|
|
self.layer.anchorPoint = point;
|
||
|
|
self.frame = originRect;
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)setArrowPosition
|
||
|
|
{
|
||
|
|
if (_priorityDirection == YBPopupMenuPriorityDirectionNone) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) {
|
||
|
|
if (_point.x + _itemWidth / 2 > YBScreenWidth - _minSpace) {
|
||
|
|
_arrowPosition = _itemWidth - (YBScreenWidth - _minSpace - _point.x);
|
||
|
|
}else if (_point.x < _itemWidth / 2 + _minSpace) {
|
||
|
|
_arrowPosition = _point.x - _minSpace;
|
||
|
|
}else {
|
||
|
|
_arrowPosition = _itemWidth / 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
}else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) {
|
||
|
|
// if (_point.y + _itemHeight / 2 > YBScreenHeight - _minSpace) {
|
||
|
|
// _arrowPosition = _itemHeight - (YBScreenHeight - _minSpace - _point.y);
|
||
|
|
// }else if (_point.y < _itemHeight / 2 + _minSpace) {
|
||
|
|
// _arrowPosition = _point.y - _minSpace;
|
||
|
|
// }else {
|
||
|
|
// _arrowPosition = _itemHeight / 2;
|
||
|
|
// }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- (void)drawRect:(CGRect)rect
|
||
|
|
{
|
||
|
|
UIBezierPath *bezierPath = [YBPopupMenuPath yb_bezierPathWithRect:rect rectCorner:_rectCorner cornerRadius:_cornerRadius borderWidth:_borderWidth borderColor:_borderColor backgroundColor:_backColor arrowWidth:_arrowWidth arrowHeight:_arrowHeight arrowPosition:_arrowPosition arrowDirection:_arrowDirection];
|
||
|
|
[bezierPath fill];
|
||
|
|
[bezierPath stroke];
|
||
|
|
}
|
||
|
|
|
||
|
|
@end
|