HyPopMenuView.m 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. //
  2. // HyPopMenuView.m
  3. // HyPopMenuView
  4. //
  5. // Created by H y on 15/9/8.
  6. // Copyright (c) 2015年 ouy.Aberi. All rights reserved.
  7. //
  8. #import "HyPopMenuView.h"
  9. #import "UIColor+ImageGetColor.h"
  10. #import <AudioToolbox/AudioToolbox.h>
  11. //#import <pop/POP.h>
  12. #import "POP.h"
  13. #define Duration 0.5
  14. #define KeyPath @"transform.scale"
  15. #define CancelStrImgaeName @"ic_live_tab_create_live_normal"
  16. #define kW [UIScreen mainScreen].bounds.size.width
  17. #define kH [UIScreen mainScreen].bounds.size.height
  18. #define SYSTEM_VERSION_LESS_THAN(v) \
  19. ([[[UIDevice currentDevice] systemVersion] compare:v \
  20. options:NSNumericSearch] == \
  21. NSOrderedAscending)
  22. #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) \
  23. ([[[UIDevice currentDevice] systemVersion] compare:v \
  24. options:NSNumericSearch] != \
  25. NSOrderedDescending)
  26. @interface HyPopMenuView ()
  27. @property (nonatomic, weak) UIView* superView;
  28. @property (nonatomic, weak) UIView* backgroundView;
  29. @property (nonatomic, weak) UIButton* disappearButton;
  30. @property (nonatomic, weak) UIView* bottomView;
  31. @property (nonatomic, assign) BOOL isOpen;
  32. @end
  33. @implementation HyPopMenuView
  34. static HyPopMenuView* _popMenuObject;
  35. static BOOL isAlpha = false;
  36. + (instancetype)allocWithZone:(struct _NSZone*)zone
  37. {
  38. _popMenuObject = [super allocWithZone:zone];
  39. return _popMenuObject;
  40. }
  41. + (instancetype)sharedPopMenuManager
  42. {
  43. _popMenuObject = [[self alloc] sharedPopMenuManager];
  44. return _popMenuObject;
  45. }
  46. - (id)copyWithZone:(NSZone*)zone
  47. {
  48. return _popMenuObject;
  49. }
  50. - (instancetype)sharedPopMenuManager
  51. {
  52. if (self == [super init])
  53. {
  54. [self setFrame:CGRectMake(0, 0, kScreenW, kScreenH)];
  55. _animationType = HyPopMenuViewAnimationTypeCenter;
  56. _backgroundType = HyPopMenuViewBackgroundTypeLightBlur;
  57. _automaticIdentificationColor = false;
  58. _popMenuSpeed = 10.f;
  59. }
  60. return self;
  61. }
  62. - (void)initUIsize
  63. {
  64. [[UIButton appearance] setExclusiveTouch:true];
  65. UIView* bottomView = [_backgroundView viewWithTag:2];
  66. if (!bottomView)
  67. {
  68. bottomView = [UIView new];
  69. [_backgroundView addSubview:bottomView];
  70. UIView *superView = [UIView new];
  71. superView.frame = _backgroundView.frame;
  72. [_backgroundView addSubview:superView];
  73. _superView = superView;
  74. [bottomView setTag:2];
  75. _bottomView = bottomView;
  76. }
  77. bottomView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
  78. bottomView.frame = CGRectMake(0, CGRectGetMaxY(self.bounds) - 49, kW, 49);
  79. bottomView.backgroundColor = kClearColor;
  80. if (_backgroundType == HyPopMenuViewBackgroundTypeDarkBlur || _backgroundType == HyPopMenuViewBackgroundTypeDarkTranslucent || _backgroundType == HyPopMenuViewBackgroundTypeGradient) {
  81. bottomView.backgroundColor = kClearColor;
  82. }
  83. UIButton* disappearButton = [_backgroundView viewWithTag:3];
  84. if (!disappearButton) {
  85. disappearButton = [UIButton buttonWithType:UIButtonTypeCustom];
  86. disappearButton.adjustsImageWhenHighlighted = NO;
  87. [_backgroundView addSubview:disappearButton];
  88. disappearButton.tag = 3;
  89. _disappearButton = disappearButton;
  90. }
  91. disappearButton.backgroundColor = kClearColor;
  92. [disappearButton setBackgroundImage:[UIImage imageNamed:CancelStrImgaeName] forState:UIControlStateNormal];
  93. [disappearButton addTarget:self action:@selector(closeMenu) forControlEvents:UIControlEventTouchUpInside];
  94. CGFloat CANCELw = 46;
  95. disappearButton.bounds = CGRectMake(0, 3, CANCELw, CANCELw);
  96. disappearButton.center = bottomView.center;
  97. }
  98. - (void)openMenu
  99. {
  100. [self addNotificationAtNotificationName:HyPopMenuViewWillShowNotification];
  101. UIView* backgroundView = [self effectsViewWithType:_backgroundType];
  102. _backgroundView = backgroundView;
  103. if (_topView) {
  104. [_backgroundView addSubview:_topView];
  105. }
  106. [self addSubview:_backgroundView];
  107. [self initUIsize];
  108. [self backgroundAnimate];
  109. [self show];
  110. }
  111. - (void)closeMenu
  112. {
  113. [self addNotificationAtNotificationName:HyPopMenuViewWillHideNotification];
  114. __weak HyPopMenuView* weakView = self;
  115. [weakView.disappearButton removeFromSuperview];
  116. [self disappearPopMenuViewAnimate];
  117. // [[UIApplication sharedApplication] keyWindow].windowLevel = UIWindowLevelNormal;
  118. [UIView animateWithDuration:0.3 animations:^{
  119. weakView.bottomView.backgroundColor = [UIColor clearColor];
  120. weakView.disappearButton.transform = CGAffineTransformMakeRotation(0);
  121. [weakView.disappearButton setAlpha:0.1f];
  122. }];
  123. double d = (weakView.dataSource.count * 0.04) + 0.3;
  124. [UIView animateKeyframesWithDuration:Duration delay:d options:0 animations:^{
  125. if (isAlpha) {
  126. [weakView.backgroundView setAlpha:0];
  127. }else{
  128. UIVisualEffectView *effect = (id)_backgroundView;
  129. effect.effect = nil;
  130. _topView.alpha = 0;
  131. }
  132. }
  133. completion:^(BOOL finished) {
  134. [weakView addNotificationAtNotificationName:HyPopMenuViewDidHideNotification];
  135. [weakView.backgroundView removeFromSuperview];
  136. weakView.isOpen = false;
  137. [self removeFromSuperview];
  138. }];
  139. }
  140. - (void)backgroundAnimate
  141. {
  142. _topView.alpha = 0.0f;
  143. __weak HyPopMenuView* weakView = self;
  144. if ([_backgroundView isKindOfClass:[UIVisualEffectView class]]) {
  145. UIVisualEffectView *effect = (id)_backgroundView;
  146. effect.effect = nil;
  147. }
  148. UIBlurEffect* effectBlur = nil;
  149. switch (_backgroundType) {
  150. case HyPopMenuViewBackgroundTypeDarkBlur:
  151. effectBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
  152. break;
  153. case HyPopMenuViewBackgroundTypeDarkTranslucent:
  154. break;
  155. case HyPopMenuViewBackgroundTypeLightBlur:
  156. effectBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
  157. break;
  158. case HyPopMenuViewBackgroundTypeGradient:
  159. break;
  160. case HyPopMenuViewBackgroundTypeLightTranslucent:
  161. break;
  162. }
  163. [UIView animateWithDuration:Duration animations:^{
  164. if (isAlpha) {
  165. [weakView.backgroundView setAlpha:1];
  166. }else{
  167. UIVisualEffectView *effect = (id)_backgroundView;
  168. effect.effect = effectBlur;
  169. _topView.alpha = 1;
  170. }
  171. weakView.disappearButton.transform = CGAffineTransformMakeRotation((M_PI / 2) / 2);
  172. }];
  173. [self showItemAnimate];
  174. }
  175. - (void)showItemAnimate
  176. {
  177. __weak HyPopMenuView* weakView = self;
  178. double d = (self.dataSource.count * 0.04) + 0.3;
  179. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(d * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  180. [weakView addNotificationAtNotificationName:HyPopMenuViewDidShowNotification];
  181. });
  182. [_dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL* _Nonnull stop) {
  183. PopMenuModel* model = obj;
  184. model.automaticIdentificationColor = weakView.automaticIdentificationColor;
  185. [model.customView removeFromSuperview];
  186. model.customView.alpha = 0.0f;
  187. [weakView.superView addSubview:model.customView];
  188. CGRect toRect;
  189. CGRect fromRect;
  190. double dy = idx * 0.035f;
  191. CFTimeInterval delay = dy + CACurrentMediaTime();
  192. switch (_animationType) {
  193. case HyPopMenuViewAnimationTypeSina:
  194. toRect = [weakView getFrameAtIndex:idx];
  195. fromRect = CGRectMake(CGRectGetMinX(toRect),
  196. CGRectGetMinY(toRect) + 130,
  197. toRect.size.width,
  198. toRect.size.height);
  199. break;
  200. case HyPopMenuViewAnimationTypeCenter:
  201. toRect = [weakView getFrameAtIndex:idx];
  202. fromRect = CGRectMake(CGRectGetMidX(weakView.frame) - CGRectGetWidth(fromRect) / 2,
  203. (CGRectGetMinY(toRect) + (kH - CGRectGetMinY(toRect))) - 25,
  204. toRect.size.width,
  205. toRect.size.height);
  206. break;
  207. case HyPopMenuViewAnimationTypeViscous:
  208. toRect = [weakView getFrameAtIndex:idx];
  209. fromRect = CGRectMake(CGRectGetMinX(toRect),
  210. CGRectGetMinY(toRect) + (kH - CGRectGetMinY(toRect)),
  211. toRect.size.width,
  212. toRect.size.height);
  213. break;
  214. case HyPopMenuViewAnimationTypeLeftAndRight:
  215. toRect = [weakView getFrameAtIndex:idx];
  216. CGFloat d = (idx % 2) == 0 ? 0:CGRectGetWidth(toRect);
  217. CGFloat x = ((idx % 2) * kW) - d;
  218. fromRect = CGRectMake(x,
  219. CGRectGetMinY(toRect) + (kH - CGRectGetMinY(toRect)),
  220. toRect.size.width,
  221. toRect.size.height);
  222. break;
  223. }
  224. [self classAnimationWithfromRect:fromRect
  225. toRect:toRect
  226. deleay:delay
  227. views:model.customView
  228. isHidd:false];
  229. PopMenuButton* button = (id)model.customView;
  230. [button addTarget:self action:@selector(selectedFunc:) forControlEvents:UIControlEventTouchUpInside];
  231. }];
  232. }
  233. - (void)classAnimationWithfromRect:(CGRect)age1
  234. toRect:(CGRect)age2
  235. deleay:(CFTimeInterval)age3
  236. views:(UIView*)age4
  237. isHidd:(BOOL)age5
  238. {
  239. __weak HyPopMenuView* weakView = self;
  240. if (_animationType == HyPopMenuViewAnimationTypeSina) {
  241. [self startSinaAnimationfromValue:age1
  242. toValue:age2
  243. delay:age3
  244. object:age4
  245. completionBlock:^(BOOL CompletionBlock) {
  246. [weakView addTap];
  247. }
  248. hideDisplay:age5];
  249. }
  250. else if (_animationType == HyPopMenuViewAnimationTypeViscous) {
  251. [self startViscousAnimationFormValue:age1
  252. ToValue:age2
  253. Delay:age3
  254. Object:age4
  255. CompletionBlock:^(BOOL CompletionBlock) {
  256. [weakView addTap];
  257. }
  258. HideDisplay:age5];
  259. }
  260. else if (_animationType == HyPopMenuViewAnimationTypeCenter) {
  261. [self startSinaAnimationfromValue:age1
  262. toValue:age2
  263. delay:age3
  264. object:age4
  265. completionBlock:^(BOOL CompletionBlock) {
  266. [weakView addTap];
  267. }
  268. hideDisplay:age5];
  269. } else if (_animationType == HyPopMenuViewAnimationTypeLeftAndRight) {
  270. [self startSinaAnimationfromValue:age1
  271. toValue:age2
  272. delay:age3
  273. object:age4
  274. completionBlock:^(BOOL CompletionBlock) {
  275. [weakView addTap];
  276. }
  277. hideDisplay:age5];
  278. }
  279. }
  280. - (void)addTap
  281. {
  282. UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self
  283. action:@selector(closeMenu)];
  284. [_backgroundView addGestureRecognizer:tap];
  285. _isOpen = true;
  286. }
  287. - (CGFloat)maxItemsMinY
  288. {
  289. CGRect rect = [self getFrameAtIndex:0];
  290. return CGRectGetMinY(rect);
  291. }
  292. - (CGRect)getFrameAtIndex:(NSUInteger)index;
  293. {
  294. NSInteger column = 2;
  295. CGFloat buttonViewWidth = MIN(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)) / column;
  296. CGFloat buttonViewHeight = (buttonViewWidth - 10);
  297. CGFloat margin = (self.frame.size.width - column * buttonViewWidth) / (column + 1);
  298. NSInteger colnumIndex = index % column;
  299. NSInteger rowIndex = index / column;
  300. NSUInteger toRows = (_dataSource.count / column);
  301. CGFloat toHeight = toRows * buttonViewHeight;
  302. CGFloat buttonViewX = (colnumIndex + 1) * margin + colnumIndex * buttonViewWidth;
  303. CGFloat buttonViewY = ((rowIndex + 1) * margin + rowIndex * buttonViewHeight) + (kH - toHeight) - 120;
  304. CGRect rect = CGRectMake(buttonViewX, buttonViewY, buttonViewWidth, buttonViewHeight);
  305. return rect;
  306. }
  307. - (void)disappearPopMenuViewAnimate
  308. {
  309. __weak HyPopMenuView* weakView = self;
  310. [_dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL* _Nonnull stop) {
  311. double d = weakView.dataSource.count * 0.04;
  312. double dy = d - idx * 0.04;
  313. PopMenuModel* model = obj;
  314. CFTimeInterval delay = dy + CACurrentMediaTime();
  315. CGRect toRect;
  316. CGRect fromRect;
  317. switch (_animationType) {
  318. case HyPopMenuViewAnimationTypeSina:
  319. fromRect = [weakView getFrameAtIndex:idx];
  320. toRect = CGRectMake(CGRectGetMinX(fromRect),
  321. kH,
  322. CGRectGetWidth(fromRect),
  323. CGRectGetHeight(fromRect));
  324. break;
  325. case HyPopMenuViewAnimationTypeCenter:
  326. fromRect = [weakView getFrameAtIndex:idx];
  327. toRect = CGRectMake(CGRectGetMidX(weakView.frame) - CGRectGetWidth(fromRect) / 2,
  328. (CGRectGetMinY(toRect) + (kH - CGRectGetMinY(toRect))) - 25,
  329. fromRect.size.width,
  330. fromRect.size.height);
  331. break;
  332. case HyPopMenuViewAnimationTypeViscous:
  333. fromRect = [weakView getFrameAtIndex:idx];
  334. toRect = CGRectMake(CGRectGetMinX(fromRect),
  335. CGRectGetMinY(fromRect) + (kH - CGRectGetMinY(fromRect)),
  336. fromRect.size.width,
  337. fromRect.size.height);
  338. break;
  339. case HyPopMenuViewAnimationTypeLeftAndRight:
  340. fromRect = [weakView getFrameAtIndex:idx];
  341. CGFloat d = (idx % 2) == 0 ? 0:CGRectGetWidth(fromRect);
  342. CGFloat x = ((idx % 2) * kW) - d;
  343. toRect = CGRectMake(x,
  344. CGRectGetMinY(fromRect) + (kH - CGRectGetMinY(fromRect)),
  345. fromRect.size.width,
  346. fromRect.size.height);
  347. break;
  348. }
  349. [self classAnimationWithfromRect:fromRect
  350. toRect:toRect
  351. deleay:delay
  352. views:model.customView
  353. isHidd:true];
  354. }];
  355. }
  356. - (__kindof UIView*)effectsViewWithType:(HyPopMenuViewBackgroundType)type
  357. {
  358. if (_backgroundView)
  359. {
  360. [_backgroundView removeFromSuperview];
  361. _backgroundView = nil;
  362. }
  363. isAlpha = true;
  364. UIView* effectView = nil;
  365. UIBlurEffect* effectBlur = nil;
  366. CAGradientLayer* gradientLayer = nil;
  367. switch (type) {
  368. case HyPopMenuViewBackgroundTypeDarkBlur:
  369. effectBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
  370. break;
  371. case HyPopMenuViewBackgroundTypeDarkTranslucent:
  372. break;
  373. case HyPopMenuViewBackgroundTypeLightBlur:
  374. effectBlur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
  375. break;
  376. case HyPopMenuViewBackgroundTypeLightTranslucent:
  377. break;
  378. case HyPopMenuViewBackgroundTypeGradient:
  379. gradientLayer = [self gradientLayerWithColor1:[UIColor colorWithWhite:1 alpha:0.1f] AtColor2:[UIColor colorWithWhite:0.0f alpha:1.0f]];
  380. break;
  381. }
  382. if (effectBlur) {
  383. effectView = [[UIVisualEffectView alloc] initWithEffect:effectBlur];
  384. isAlpha = false;
  385. }
  386. else {
  387. effectView = [UIView new];
  388. if (gradientLayer) {
  389. [effectView.layer addSublayer:gradientLayer];
  390. }
  391. else {
  392. effectView.backgroundColor = [UIColor colorWithWhite:(CGFloat)(type == HyPopMenuViewBackgroundTypeLightTranslucent) alpha:0.95];
  393. }
  394. }
  395. effectView.frame = self.bounds;
  396. if (isAlpha) effectView.alpha = 0.0f;
  397. _superView.frame = _backgroundView.bounds;
  398. return effectView;
  399. }
  400. - (CAGradientLayer*)gradientLayerWithColor1:(UIColor*)color1 AtColor2:(UIColor*)color2
  401. {
  402. CAGradientLayer* layer = [CAGradientLayer new];
  403. layer.colors = @[ (__bridge id)color1.CGColor, (__bridge id)color2.CGColor];
  404. layer.startPoint = CGPointMake(0.5f, -0.5);
  405. layer.endPoint = CGPointMake(0.5, 1);
  406. layer.frame = self.bounds;
  407. return layer;
  408. }
  409. - (void)selectedFunc:(PopMenuButton*)sender
  410. {
  411. __weak HyPopMenuView* weakView = self;
  412. for (PopMenuModel *obj in _dataSource)
  413. {
  414. PopMenuModel* model = obj;
  415. PopMenuButton* button = (id)model.customView;
  416. if (sender == button) {
  417. [sender selectdAnimation];
  418. }else{
  419. [button cancelAnimation];
  420. }
  421. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  422. [model performSelector:@selector(_obj)];
  423. });
  424. }
  425. NSUInteger idx = [_dataSource indexOfObject:sender.model];
  426. if (sender.model.transitionType == PopMenuTransitionTypeCustomizeApi) {
  427. sender.block = ^(PopMenuButton *btn){
  428. //[self.backgroundView insertSubview:btn atIndex:[self.backgroundView subviews].count];
  429. if ([weakView.delegate respondsToSelector:@selector(popMenuView:didSelectItemAtIndex:)]) {
  430. [weakView.delegate popMenuView:weakView didSelectItemAtIndex:idx];
  431. }
  432. [weakView close];
  433. };
  434. }else{
  435. if ([weakView.delegate respondsToSelector:@selector(popMenuView:didSelectItemAtIndex:)]) {
  436. [weakView.delegate popMenuView:weakView didSelectItemAtIndex:idx];
  437. }
  438. [self close];
  439. }
  440. }
  441. - (void)close
  442. {
  443. __weak HyPopMenuView* weakView = self;
  444. [UIView animateWithDuration:0.5 delay:0.0 options:0 animations:^{
  445. _superView.alpha=0.0;
  446. if (isAlpha) {
  447. [weakView.backgroundView setAlpha:0];
  448. }else{
  449. UIVisualEffectView *effect = (id)_backgroundView;
  450. effect.effect = nil;
  451. _topView.alpha = 0;
  452. }
  453. weakView.bottomView.backgroundColor = [UIColor clearColor];
  454. weakView.disappearButton.transform = CGAffineTransformMakeRotation(0);
  455. [weakView.disappearButton setAlpha:0.1f];
  456. } completion:^(BOOL finished) {
  457. [weakView.backgroundView removeFromSuperview];
  458. [self removeFromSuperview];
  459. }];
  460. }
  461. - (void)setDataSource:(NSArray*)dataSource
  462. {
  463. NSMutableArray* tepmArr = [NSMutableArray arrayWithCapacity:MIN(9, dataSource.count)];
  464. [dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL* _Nonnull stop) {
  465. if (idx == 9) {
  466. *stop = true;
  467. return;
  468. }
  469. [tepmArr addObject:obj];
  470. }];
  471. _dataSource = [NSArray arrayWithArray:tepmArr];
  472. }
  473. - (void)startViscousAnimationFormValue:(CGRect)fromValue
  474. ToValue:(CGRect)toValue
  475. Delay:(CFTimeInterval)delay
  476. Object:(UIView*)obj
  477. CompletionBlock:(void (^)(BOOL CompletionBlock))completionBlock
  478. HideDisplay:(BOOL)hideDisplay
  479. {
  480. CGFloat toV, fromV;
  481. CGFloat springBounciness = 8.f;
  482. toV = !hideDisplay;
  483. fromV = hideDisplay;
  484. if (hideDisplay) {
  485. POPBasicAnimation* basicAnimationCenter = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
  486. basicAnimationCenter.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(toValue), CGRectGetMidY(toValue))];
  487. basicAnimationCenter.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(fromValue), CGRectGetMidY(fromValue))];
  488. basicAnimationCenter.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  489. basicAnimationCenter.beginTime = delay;
  490. basicAnimationCenter.duration = 0.18;
  491. [obj pop_addAnimation:basicAnimationCenter forKey:basicAnimationCenter.name];
  492. POPBasicAnimation* basicAnimationScale = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleX];
  493. basicAnimationScale.removedOnCompletion = YES;
  494. basicAnimationScale.beginTime = delay;
  495. basicAnimationScale.toValue = @(0.7);
  496. basicAnimationScale.fromValue = @(1);
  497. basicAnimationScale.duration = 0.18;
  498. basicAnimationScale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  499. [obj.layer pop_addAnimation:basicAnimationScale forKey:basicAnimationScale.name];
  500. }
  501. else {
  502. POPSpringAnimation* basicAnimationCenter = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
  503. basicAnimationCenter.beginTime = delay;
  504. basicAnimationCenter.springSpeed = _popMenuSpeed;
  505. basicAnimationCenter.springBounciness = springBounciness;
  506. basicAnimationCenter.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(toValue), CGRectGetMidY(toValue))];
  507. basicAnimationCenter.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(fromValue), CGRectGetMidY(fromValue))];
  508. POPBasicAnimation* basicAnimationScale = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleX];
  509. basicAnimationScale.beginTime = delay;
  510. basicAnimationScale.toValue = @(1);
  511. basicAnimationScale.fromValue = @(0.7);
  512. basicAnimationScale.duration = 0.3f;
  513. basicAnimationScale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  514. [obj.layer pop_addAnimation:basicAnimationScale forKey:basicAnimationScale.name];
  515. POPBasicAnimation* basicAnimationAlpha = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha];
  516. basicAnimationAlpha.removedOnCompletion = YES;
  517. basicAnimationAlpha.duration = 0.1f;
  518. basicAnimationAlpha.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  519. basicAnimationAlpha.beginTime = delay;
  520. basicAnimationAlpha.toValue = @(toV);
  521. basicAnimationAlpha.fromValue = @(fromV);
  522. [obj pop_addAnimation:basicAnimationAlpha forKey:basicAnimationAlpha.name];
  523. [obj pop_addAnimation:basicAnimationCenter forKey:basicAnimationCenter.name];
  524. [basicAnimationCenter setCompletionBlock:^(POPAnimation* spring, BOOL Completion) {
  525. if (!completionBlock) {
  526. return;
  527. }
  528. if (Completion) {
  529. completionBlock(Completion);
  530. }
  531. }];
  532. }
  533. }
  534. - (void)startSinaAnimationfromValue:(CGRect)fromValue
  535. toValue:(CGRect)toValue
  536. delay:(CFTimeInterval)delay
  537. object:(UIView*)obj
  538. completionBlock:(void (^)(BOOL CompletionBlock))completionBlock
  539. hideDisplay:(BOOL)hideDisplay
  540. {
  541. CGFloat toV, fromV;
  542. CGFloat springBounciness = 10.f;
  543. toV = !hideDisplay;
  544. fromV = hideDisplay;
  545. if (hideDisplay) {
  546. POPBasicAnimation* basicAnimationCenter = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
  547. basicAnimationCenter.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(toValue), CGRectGetMidY(toValue))];
  548. basicAnimationCenter.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(fromValue), CGRectGetMidY(fromValue))];
  549. basicAnimationCenter.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  550. basicAnimationCenter.beginTime = delay;
  551. basicAnimationCenter.duration = 0.18;
  552. [obj pop_addAnimation:basicAnimationCenter forKey:basicAnimationCenter.name];
  553. POPBasicAnimation* basicAnimationScale = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
  554. basicAnimationScale.removedOnCompletion = YES;
  555. basicAnimationScale.beginTime = delay;
  556. basicAnimationScale.toValue = [NSValue valueWithCGPoint:CGPointMake(0.7, 0.7)];
  557. basicAnimationScale.fromValue = [NSValue valueWithCGPoint:CGPointMake(1, 1)];
  558. basicAnimationScale.duration = 0.18;
  559. basicAnimationScale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  560. [obj.layer pop_addAnimation:basicAnimationScale forKey:basicAnimationScale.name];
  561. [basicAnimationScale setCompletionBlock:^(POPAnimation* s, BOOL b) {
  562. PopMenuButton* btn = (id)obj;
  563. [btn.model performSelector:@selector(_obj)];
  564. }];
  565. }
  566. else {
  567. POPSpringAnimation* springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
  568. springAnimation.removedOnCompletion = YES;
  569. springAnimation.beginTime = delay;
  570. springAnimation.springBounciness = springBounciness; // value between 0-20
  571. springAnimation.springSpeed = _popMenuSpeed; // value between 0-20
  572. springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(toValue), CGRectGetMidY(toValue))];
  573. springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(fromValue), CGRectGetMidY(fromValue))];
  574. POPBasicAnimation* basicAnimationAlpha = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha];
  575. basicAnimationAlpha.removedOnCompletion = YES;
  576. basicAnimationAlpha.duration = 0.2;
  577. basicAnimationAlpha.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  578. basicAnimationAlpha.beginTime = delay;
  579. basicAnimationAlpha.toValue = @(toV);
  580. basicAnimationAlpha.fromValue = @(fromV);
  581. [obj pop_addAnimation:basicAnimationAlpha forKey:basicAnimationAlpha.name];
  582. [obj pop_addAnimation:springAnimation forKey:springAnimation.name];
  583. [springAnimation setCompletionBlock:^(POPAnimation* spring, BOOL Completion) {
  584. if (!completionBlock) {
  585. return;
  586. }
  587. if (Completion) {
  588. completionBlock(Completion);
  589. }
  590. }];
  591. }
  592. }
  593. - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag
  594. {
  595. CABasicAnimation* cab = (CABasicAnimation*)anim;
  596. if ([cab.keyPath isEqualToString:@"transform.scale"]) {
  597. }
  598. }
  599. - (void)playSoundName:(NSString*)name
  600. ForType:(NSString*)type
  601. {
  602. NSString* AudioName = [NSString stringWithFormat:@"%@.%@", name, type];
  603. NSURL* url = [[NSBundle mainBundle] URLForResource:AudioName withExtension:nil];
  604. SystemSoundID soundID = 0;
  605. AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
  606. AudioServicesPlaySystemSound(soundID);
  607. }
  608. - (void)show
  609. {
  610. UIWindow *window = (id)[self getMainView];
  611. if (!window)
  612. {
  613. window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  614. }
  615. [window makeKeyAndVisible];
  616. [window addSubview:self];
  617. }
  618. - (UIView *)getMainView {
  619. if (SYSTEM_VERSION_LESS_THAN(@"8.0")) {
  620. UIWindow *window = [[UIApplication sharedApplication] keyWindow];
  621. if (!window)
  622. window = [[UIApplication sharedApplication].windows objectAtIndex:0];
  623. return [window subviews].lastObject;
  624. } else {
  625. UIWindow *window =[[UIApplication sharedApplication] keyWindow];
  626. if (window == nil)
  627. window = [[[UIApplication sharedApplication] delegate] window];//#14
  628. return window;
  629. }
  630. }
  631. - (BOOL)isOpenMenu
  632. {
  633. return _isOpen;
  634. }
  635. - (void)addNotificationAtNotificationName:(NSString*)notificationNmae
  636. {
  637. NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
  638. [notificationCenter postNotificationName:notificationNmae object:self];
  639. }
  640. - (void)setTopView:(UIView*)topView
  641. {
  642. if (_topView) {
  643. [_topView removeFromSuperview];
  644. }
  645. _topView = topView;
  646. }
  647. - (void)dealloc
  648. {
  649. }
  650. - (void)_obj {}
  651. @end
  652. NSString* const HyPopMenuViewWillShowNotification = @"HyPopMenuViewWillShowNotification";
  653. NSString* const HyPopMenuViewDidShowNotification = @"HyPopMenuViewDidShowNotification";
  654. NSString* const HyPopMenuViewWillHideNotification = @"HyPopMenuViewWillHideNotification";
  655. NSString* const HyPopMenuViewDidHideNotification = @"HyPopMenuViewDidHideNotification";