前言
之前有在一些項(xiàng)目中用到過一些帶箭頭的彈出菜單试幽,其實(shí)這個(gè)樣式的UI組件還是比較常見的,QQ和微信虚青,支付寶等等很多App都有類似的UI組件涩咖,所以我把之前項(xiàng)目中的相關(guān)代碼抽取出來,然后做了個(gè)封裝级野,所有就有了今天這篇內(nèi)容页屠。
其實(shí)也不算直接封裝之前的代碼,之前的實(shí)現(xiàn)方式是用modal出控制器蓖柔,然后自定義轉(zhuǎn)場動(dòng)畫辰企,同時(shí)在轉(zhuǎn)場代理中通過 UIPresentationController 改變視圖的frame實(shí)現(xiàn)的,同時(shí)箭頭也是用一個(gè)帶箭頭的背景圖實(shí)現(xiàn)的况鸣。不過當(dāng)前封裝的這個(gè)UI視圖則是放棄了帶控制器的這種方式牢贸,是用純視圖的組合封裝來實(shí)現(xiàn)的。
實(shí)現(xiàn)效果
使用方式
使用方式很簡單懒闷,先將CWPopMenu.h和CWPopMenu.m這兩個(gè)文件拖到項(xiàng)目里十减。
導(dǎo)入頭文件之后直接初始化并調(diào)用showMenu顯示
self.menu = [[CWPopMenu alloc]initWithArrow:CGPointMake(self.view.frame.size.width-25, _sumHeight) menuSize:CGSizeMake(130, 200) arrowStyle:CWPopMenuArrowTopfooter];
//代理是UITableView的代理方法
_menu.dataSource = self;
_menu.delegate = self;
//設(shè)置菜單的背景色(默認(rèn)是白色)
_menu.menuViewBgColor = [UIColor whiteColor];
//YES代表使用動(dòng)畫
[_menu showMenu:YES];
方法以及參數(shù)的意義
/**
@param point 箭頭箭尖的坐標(biāo)
@param size 菜單的視圖的大小
@param position 箭頭的方位(同時(shí)決定縮放動(dòng)畫的錨點(diǎn))
*/
- (instancetype)initWithArrow:(CGPoint)point menuSize:(CGSize)size arrowStyle:(CWPopMenuArrowPosition)position;
//顯示 *屬性設(shè)置需要在show之前設(shè)置才會(huì)生效*
- (void)showMenu:(BOOL)animated;
//關(guān)閉
- (void)closeMenu:(BOOL)animated;
部分可設(shè)置的屬性
//箭頭在上或者下邊的前中后位置枚舉(從左到右)
typedef NS_ENUM(NSInteger, CWPopMenuArrowPosition) {
CWPopMenuArrowTopHeader = 0,//默認(rèn)從0開始
CWPopMenuArrowTopCenter,
CWPopMenuArrowTopfooter,
CWPopMenuArrowBottomHeader,
CWPopMenuArrowBottomCenter,
CWPopMenuArrowBottomfooter,
};
//箭頭方位的枚舉會(huì)決定箭頭在菜單視圖的位置栈幸,以及縮放動(dòng)畫的錨點(diǎn)位置
//菜單蒙版的透明度 default bgViewAlpha = 0.2;設(shè)置alpha屬性時(shí)會(huì)被bgAlpha接管
@property (nonatomic, assign)CGFloat bgAlpha;
//菜單背景色 default menuViewBgColor = [UIColor whiteColor];
@property (nonatomic, assign)UIColor *menuViewBgColor;
//菜單圓角 default menuRadius = 5.f;
@property (nonatomic, assign)CGFloat menuRadius;
//箭頭寬度 default arrowWidth = 15.f;
@property (nonatomic, assign)CGFloat arrowWidth;
//箭頭高度 default arrowHeight = 10.f;
@property (nonatomic, assign)CGFloat arrowHeight;
其實(shí)這個(gè)UI視圖是沒什么難度的東西,菜單核心視圖就是個(gè)UITableView帮辟,就是箭頭繪制要進(jìn)行各種判斷寫起來稍微麻煩點(diǎn)速址。
核心方法
//根據(jù)位置枚舉以及箭頭高度和寬度計(jì)算繪制箭頭的點(diǎn)
- (void)computeArrowPosition:(CWPopMenuArrowPosition)arrowPosition
{
CGRect _menuFrame = _menuView.frame;
CGFloat menuX = _menuFrame.origin.x;
CGFloat menuY = _menuFrame.origin.y;
CGFloat menuWidth = _menuFrame.size.width;
CGFloat menuHeight = _menuFrame.size.height;
switch (_arrowPosition) {
case CWPopMenuArrowTopHeader:
{
CGPoint origin = CGPointMake(menuX+distance, menuY);
CGPoint peak = CGPointMake(menuX+_arrowWidth*0.5 +distance, menuY-_arrowHeight);
CGPoint terminus = CGPointMake(menuX+_arrowWidth+distance, menuY);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
case CWPopMenuArrowTopCenter:
{
CGPoint origin = CGPointMake(menuX+(menuWidth-_arrowWidth)*0.5, menuY);
CGPoint peak = CGPointMake(menuX+menuWidth*0.5, menuY-_arrowHeight);
CGPoint terminus = CGPointMake(menuX+(menuWidth+_arrowWidth)*0.5, menuY);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
case CWPopMenuArrowTopfooter:
{
CGPoint origin = CGPointMake(menuX+menuWidth-_arrowWidth-distance, menuY);
CGPoint peak = CGPointMake(menuX+menuWidth-_arrowWidth*0.5-distance, menuY-_arrowHeight);
CGPoint terminus = CGPointMake(menuX+menuWidth-distance, menuY);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
case CWPopMenuArrowBottomHeader:
{
CGPoint origin = CGPointMake(menuX+distance, menuY+menuHeight);
CGPoint peak = CGPointMake(menuX+_arrowWidth*0.5+distance, menuY+menuHeight+_arrowHeight);
CGPoint terminus = CGPointMake(menuX+_arrowWidth+distance, menuY+menuHeight);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
case CWPopMenuArrowBottomCenter:
{
CGPoint origin = CGPointMake(menuX+(menuWidth-_arrowWidth)*0.5, menuY+menuHeight);
CGPoint peak = CGPointMake(menuX+menuWidth*0.5, menuY+menuHeight+_arrowHeight);
CGPoint terminus = CGPointMake(menuX+(menuWidth+_arrowWidth)*0.5, menuY+menuHeight);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
case CWPopMenuArrowBottomfooter:
{
CGPoint origin = CGPointMake(menuX+menuWidth-_arrowWidth-distance, menuY+menuHeight);
CGPoint peak = CGPointMake(menuX+menuWidth-_arrowWidth*0.5-distance, menuY+menuHeight+_arrowHeight);
CGPoint terminus = CGPointMake(menuX+menuWidth-distance, menuY+menuHeight);
[self drawArrowInLayer:origin peak:peak terminus:terminus];
}
break;
default:
break;
}
}
//繪制箭頭
- (void)drawArrowInLayer:(CGPoint)origin peak:(CGPoint)peak terminus:(CGPoint)terminus{
//定義畫圖的path
self.shLayer = [[CAShapeLayer alloc]init];
UIBezierPath *path = [[UIBezierPath alloc] init];
_shLayer.fillColor = self.menuViewBgColor.CGColor;
//path移動(dòng)到開始畫圖的位置
[path moveToPoint:origin];
[path addLineToPoint:peak];
[path addLineToPoint:terminus];
_shLayer.path = [path CGPath];
//關(guān)閉path
[path closePath];
[self.layer addSublayer:_shLayer];
}
寫在最后
希望對看到的人有些幫助,如果各位看官覺得有所幫助請點(diǎn)個(gè)贊由驹。