UIView+NTES.m 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. //
  2. // UIView+NTES.m
  3. // NIMDemo
  4. //
  5. // Created by ght on 15-1-31.
  6. // Copyright (c) 2015年 Netease. All rights reserved.
  7. //
  8. #import "UIView+NTES.h"
  9. #import <objc/runtime.h>
  10. @implementation UIView (NTES)
  11. - (CGFloat)left {
  12. return self.frame.origin.x;
  13. }
  14. ///////////////////////////////////////////////////////////////////////////////////////////////////
  15. - (void)setLeft:(CGFloat)x {
  16. CGRect frame = self.frame;
  17. frame.origin.x = x;
  18. self.frame = frame;
  19. }
  20. ///////////////////////////////////////////////////////////////////////////////////////////////////
  21. - (CGFloat)top {
  22. return self.frame.origin.y;
  23. }
  24. ///////////////////////////////////////////////////////////////////////////////////////////////////
  25. - (void)setTop:(CGFloat)y {
  26. CGRect frame = self.frame;
  27. frame.origin.y = y;
  28. self.frame = frame;
  29. }
  30. ///////////////////////////////////////////////////////////////////////////////////////////////////
  31. - (CGFloat)right {
  32. return self.frame.origin.x + self.frame.size.width;
  33. }
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////
  35. - (void)setRight:(CGFloat)right {
  36. CGRect frame = self.frame;
  37. frame.origin.x = right - frame.size.width;
  38. self.frame = frame;
  39. }
  40. ///////////////////////////////////////////////////////////////////////////////////////////////////
  41. - (CGFloat)bottom {
  42. return self.frame.origin.y + self.frame.size.height;
  43. }
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////
  45. - (void)setBottom:(CGFloat)bottom {
  46. CGRect frame = self.frame;
  47. frame.origin.y = bottom - frame.size.height;
  48. self.frame = frame;
  49. }
  50. ///////////////////////////////////////////////////////////////////////////////////////////////////
  51. - (CGFloat)centerX {
  52. return self.center.x;
  53. }
  54. ///////////////////////////////////////////////////////////////////////////////////////////////////
  55. - (void)setCenterX:(CGFloat)centerX {
  56. self.center = CGPointMake(centerX, self.center.y);
  57. }
  58. ///////////////////////////////////////////////////////////////////////////////////////////////////
  59. - (CGFloat)centerY {
  60. return self.center.y;
  61. }
  62. ///////////////////////////////////////////////////////////////////////////////////////////////////
  63. - (void)setCenterY:(CGFloat)centerY {
  64. self.center = CGPointMake(self.center.x, centerY);
  65. }
  66. ///////////////////////////////////////////////////////////////////////////////////////////////////
  67. - (CGFloat)width {
  68. return self.frame.size.width;
  69. }
  70. ///////////////////////////////////////////////////////////////////////////////////////////////////
  71. - (void)setWidth:(CGFloat)width {
  72. CGRect frame = self.frame;
  73. frame.size.width = width;
  74. self.frame = frame;
  75. }
  76. ///////////////////////////////////////////////////////////////////////////////////////////////////
  77. - (CGFloat)height {
  78. return self.frame.size.height;
  79. }
  80. ///////////////////////////////////////////////////////////////////////////////////////////////////
  81. - (void)setHeight:(CGFloat)height {
  82. CGRect frame = self.frame;
  83. frame.size.height = height;
  84. self.frame = frame;
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////////////////////////
  87. - (CGPoint)origin {
  88. return self.frame.origin;
  89. }
  90. ///////////////////////////////////////////////////////////////////////////////////////////////////
  91. - (void)setOrigin:(CGPoint)origin {
  92. CGRect frame = self.frame;
  93. frame.origin = origin;
  94. self.frame = frame;
  95. }
  96. ///////////////////////////////////////////////////////////////////////////////////////////////////
  97. - (CGSize)size {
  98. return self.frame.size;
  99. }
  100. ///////////////////////////////////////////////////////////////////////////////////////////////////
  101. - (void)setSize:(CGSize)size {
  102. CGRect frame = self.frame;
  103. frame.size = size;
  104. self.frame = frame;
  105. }
  106. - (UIViewController *)viewController{
  107. for (UIView* next = self; next; next = next.superview) {
  108. UIResponder* nextResponder = [next nextResponder];
  109. if ([nextResponder isKindOfClass:[UIViewController class]]) {
  110. return (UIViewController*)nextResponder;
  111. }
  112. }
  113. return nil;
  114. }
  115. @end
  116. @implementation UIView(NTESPresent)
  117. static char PresentedViewAddress; //被Present的View
  118. static char PresentingViewAddress; //正在Present其他视图的view
  119. #define AnimateDuartion .25f
  120. - (void)presentView:(UIView*)view animated:(BOOL)animated complete:(void(^)(void)) complete{
  121. if (!self.window) {
  122. return;
  123. }
  124. [self.window addSubview:view];
  125. objc_setAssociatedObject(self, &PresentedViewAddress, view, OBJC_ASSOCIATION_RETAIN);
  126. objc_setAssociatedObject(view, &PresentingViewAddress, self, OBJC_ASSOCIATION_RETAIN);
  127. if (animated) {
  128. [self doAlertAnimate:view complete:complete];
  129. }else{
  130. view.center = self.window.center;
  131. }
  132. }
  133. - (UIView *)presentedView{
  134. UIView * view = objc_getAssociatedObject(self, &PresentedViewAddress);
  135. return view;
  136. }
  137. - (void)dismissPresentedView:(BOOL)animated complete:(void(^)(void)) complete{
  138. UIView * view = objc_getAssociatedObject(self, &PresentedViewAddress);
  139. if (animated) {
  140. [self doHideAnimate:view complete:complete];
  141. }else{
  142. [view removeFromSuperview];
  143. [self cleanAssocaiteObject];
  144. }
  145. }
  146. - (void)hideSelf:(BOOL)animated complete:(void(^)(void)) complete{
  147. UIView * baseView = objc_getAssociatedObject(self, &PresentingViewAddress);
  148. if (!baseView) {
  149. return;
  150. }
  151. [baseView dismissPresentedView:animated complete:complete];
  152. [self cleanAssocaiteObject];
  153. }
  154. - (void)onPressBkg:(id)sender{
  155. [self dismissPresentedView:YES complete:nil];
  156. }
  157. #pragma mark - Animation
  158. - (void)doAlertAnimate:(UIView*)view complete:(void(^)(void)) complete{
  159. CGRect bounds = view.bounds;
  160. // 放大
  161. CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
  162. scaleAnimation.duration = AnimateDuartion;
  163. scaleAnimation.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 1, 1)];
  164. scaleAnimation.toValue = [NSValue valueWithCGRect:bounds];
  165. // 移动
  166. CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
  167. moveAnimation.duration = AnimateDuartion;
  168. moveAnimation.fromValue = [NSValue valueWithCGPoint:[self.superview convertPoint:self.center toView:nil]];
  169. moveAnimation.toValue = [NSValue valueWithCGPoint:self.window.center];
  170. CAAnimationGroup *group = [CAAnimationGroup animation];
  171. group.beginTime = CACurrentMediaTime();
  172. group.duration = AnimateDuartion;
  173. group.animations = [NSArray arrayWithObjects:scaleAnimation,moveAnimation,nil];
  174. group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  175. group.fillMode = kCAFillModeForwards;
  176. group.removedOnCompletion = NO;
  177. group.autoreverses = NO;
  178. [self hideAllSubView:view];
  179. [view.layer addAnimation:group forKey:@"groupAnimationAlert"];
  180. __weak UIView * wself = self;
  181. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AnimateDuartion * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  182. view.layer.bounds = bounds;
  183. view.layer.position = wself.superview.center;
  184. [wself showAllSubView:view];
  185. if (complete) {
  186. complete();
  187. }
  188. });
  189. }
  190. - (void)doHideAnimate:(UIView*)alertView complete:(void(^)()) complete{
  191. if (!alertView) {
  192. return;
  193. }
  194. // 缩小
  195. CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
  196. scaleAnimation.duration = AnimateDuartion;
  197. scaleAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 1, 1)];
  198. CGPoint position = self.center;
  199. // 移动
  200. CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
  201. moveAnimation.duration = AnimateDuartion;
  202. moveAnimation.toValue = [NSValue valueWithCGPoint:[self.superview convertPoint:self.center toView:nil]];
  203. CAAnimationGroup *group = [CAAnimationGroup animation];
  204. group.beginTime = CACurrentMediaTime();
  205. group.duration = AnimateDuartion;
  206. group.animations = [NSArray arrayWithObjects:scaleAnimation,moveAnimation,nil];
  207. group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  208. group.fillMode = kCAFillModeForwards;
  209. group.removedOnCompletion = NO;
  210. group.autoreverses = NO;
  211. alertView.layer.bounds = self.bounds;
  212. alertView.layer.position = position;
  213. alertView.layer.needsDisplayOnBoundsChange = YES;
  214. [self hideAllSubView:alertView];
  215. alertView.backgroundColor = [UIColor clearColor];
  216. [alertView.layer addAnimation:group forKey:@"groupAnimationHide"];
  217. __weak UIView * wself = self;
  218. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AnimateDuartion * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  219. [alertView removeFromSuperview];
  220. [wself cleanAssocaiteObject];
  221. [wself showAllSubView:alertView];
  222. if (complete) {
  223. complete();
  224. }
  225. });
  226. }
  227. static char *HideViewsAddress = "hideViewsAddress";
  228. - (void)hideAllSubView:(UIView*)view{
  229. for (UIView * subView in view.subviews) {
  230. NSMutableArray *array = [[NSMutableArray alloc] init];
  231. if (subView.hidden) {
  232. [array addObject:subView];
  233. }
  234. objc_setAssociatedObject(self, &HideViewsAddress, array, OBJC_ASSOCIATION_RETAIN);
  235. subView.hidden = YES;
  236. }
  237. }
  238. - (void)showAllSubView:(UIView*)view{
  239. NSMutableArray *array = objc_getAssociatedObject(self,&HideViewsAddress);
  240. for (UIView * subView in view.subviews) {
  241. subView.hidden = [array containsObject:subView];
  242. }
  243. }
  244. - (void)cleanAssocaiteObject{
  245. objc_setAssociatedObject(self,&PresentedViewAddress,nil,OBJC_ASSOCIATION_RETAIN);
  246. objc_setAssociatedObject(self,&PresentingViewAddress,nil,OBJC_ASSOCIATION_RETAIN);
  247. objc_setAssociatedObject(self,&HideViewsAddress,nil, OBJC_ASSOCIATION_RETAIN);
  248. }
  249. @end