UINavigationController+CCProgress.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //
  2. // UINavigationController+SGProgress.m
  3. // NavigationProgress
  4. //
  5. // Created by Shawn Gryschuk on 2013-09-19.
  6. // Copyright (c) 2013 Shawn Gryschuk. All rights reserved.
  7. //
  8. // Modify Marino Faggiana
  9. #import "UINavigationController+CCProgress.h"
  10. #import "CCProgressView.h"
  11. #define SGMaskColor [UIColor colorWithWhite:0 alpha:0.4]
  12. NSInteger const SGProgressMasktagId = 221222322;
  13. NSInteger const SGProgressMiniMasktagId = 221222321;
  14. CGFloat const SGProgressBarHeight = 2.0;
  15. @implementation UINavigationController (SGProgress)
  16. - (CCProgressView *)progressView
  17. {
  18. CCProgressView *_progressView;
  19. for (UIView *subview in [self.navigationBar subviews])
  20. {
  21. if ([subview isKindOfClass:[CCProgressView class]])
  22. {
  23. _progressView = (CCProgressView *)subview;
  24. }
  25. }
  26. if (!_progressView)
  27. {
  28. CGRect slice, remainder;
  29. CGRectDivide(self.navigationBar.bounds, &slice, &remainder, SGProgressBarHeight, CGRectMaxYEdge);
  30. _progressView = [[CCProgressView alloc] initWithFrame:slice];
  31. _progressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
  32. [self.navigationBar addSubview:_progressView];
  33. }
  34. return _progressView;
  35. }
  36. - (UIView *)topMask
  37. {
  38. UIView *topMask;
  39. for (UIView *subview in [self.view subviews])
  40. {
  41. if (subview.tag == SGProgressMiniMasktagId)
  42. {
  43. topMask = subview;
  44. }
  45. }
  46. return topMask;
  47. }
  48. - (UIView *)bottomMask
  49. {
  50. UIView *bottomMask;
  51. for (UIView *subview in [self.view subviews])
  52. {
  53. if (subview.tag == SGProgressMasktagId)
  54. {
  55. bottomMask = subview;
  56. }
  57. }
  58. return bottomMask;
  59. }
  60. - (BOOL)hasCCProgressMask
  61. {
  62. for (UIView *subview in [self.view subviews])
  63. {
  64. if (subview.tag == SGProgressMiniMasktagId || subview.tag == SGProgressMasktagId)
  65. {
  66. return YES;
  67. }
  68. }
  69. return NO;
  70. }
  71. - (void)setupCCProgressMask
  72. {
  73. self.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
  74. UIView *topMask = [self topMask];
  75. UIView *bottomMask = [self bottomMask];
  76. if (!topMask)
  77. {
  78. topMask = [[UIView alloc] init];
  79. topMask.tag = SGProgressMiniMasktagId;
  80. topMask.backgroundColor = SGMaskColor;
  81. topMask.alpha = 0;
  82. [self.view addSubview:topMask];
  83. }
  84. if (!bottomMask)
  85. {
  86. bottomMask = [[UIView alloc] init];
  87. bottomMask.tag = SGProgressMasktagId;
  88. bottomMask.backgroundColor = SGMaskColor;
  89. bottomMask.alpha = 0;
  90. [self.view addSubview:bottomMask];
  91. }
  92. [self updateCCProgressMaskFrame];
  93. [UIView animateWithDuration:0.3 animations:^{
  94. topMask.alpha = 1;
  95. bottomMask.alpha = 1;
  96. }];
  97. }
  98. - (void)updateCCProgressMaskFrame
  99. {
  100. CGFloat width = CGRectGetWidth(self.view.bounds);
  101. CGFloat height = CGRectGetMaxY(self.navigationBar.frame) - CGRectGetHeight([[self progressView] frame]);
  102. [[self topMask] setFrame:CGRectMake(0, 0, width, height)];
  103. CGRect slice, remainder;
  104. CGRectDivide(self.view.bounds, &slice, &remainder, CGRectGetMaxY(self.navigationBar.frame) + 0.5, CGRectMinYEdge);
  105. [[self bottomMask] setFrame:remainder];
  106. }
  107. - (void)removeCCMask
  108. {
  109. for (UIView *subview in [self.view subviews])
  110. {
  111. if (subview.tag == SGProgressMasktagId || subview.tag == SGProgressMiniMasktagId)
  112. {
  113. [UIView animateWithDuration:0.3 animations:^{
  114. subview.alpha = 0;
  115. } completion:^(BOOL finished) {
  116. [subview removeFromSuperview];
  117. self.view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
  118. }];
  119. }
  120. }
  121. }
  122. - (void)resetTitle
  123. {
  124. BOOL titleChanged = [[[NSUserDefaults standardUserDefaults] objectForKey:kSGProgressTitleChanged] boolValue];
  125. if(titleChanged)
  126. {
  127. NSString *oldTitle = [[NSUserDefaults standardUserDefaults] objectForKey:kSGProgressOldTitle];
  128. //add animation
  129. self.visibleViewController.navigationItem.title = oldTitle;
  130. }
  131. [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:kSGProgressTitleChanged];
  132. [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:kSGProgressOldTitle];
  133. [[NSUserDefaults standardUserDefaults] synchronize];
  134. }
  135. - (void)changeCCProgressWithTitle:(NSString *)title
  136. {
  137. BOOL titleAlreadyChanged = [[[NSUserDefaults standardUserDefaults] objectForKey:kSGProgressTitleChanged] boolValue];
  138. if(!titleAlreadyChanged)
  139. {
  140. NSString *oldTitle = self.visibleViewController.navigationItem.title;
  141. [[NSUserDefaults standardUserDefaults] setObject:oldTitle forKey:kSGProgressOldTitle];
  142. [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:kSGProgressTitleChanged];
  143. [[NSUserDefaults standardUserDefaults] synchronize];
  144. //add animation
  145. self.visibleViewController.navigationItem.title = title;
  146. }
  147. }
  148. #pragma mark - UIViewController
  149. - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
  150. {
  151. if ([self hasCCProgressMask])
  152. {
  153. __weak typeof(self)weakSelf = self;
  154. __block NSTimeInterval timeInterval = 0;
  155. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  156. while (timeInterval <= duration) {
  157. [NSThread sleepForTimeInterval:0.1];
  158. timeInterval += 0.1;
  159. dispatch_async(dispatch_get_main_queue(), ^{
  160. [weakSelf updateCCProgressMaskFrame];
  161. });
  162. }
  163. });
  164. }
  165. }
  166. #pragma mark user functions
  167. - (void)showCCProgress
  168. {
  169. [self showCCProgressWithDuration:3];
  170. }
  171. - (void)showCCProgressWithDuration:(float)duration
  172. {
  173. CCProgressView *progressView = [self progressView];
  174. [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  175. progressView.progress = 1;
  176. } completion:^(BOOL finished) {
  177. [UIView animateWithDuration:0.5 animations:^{
  178. progressView.alpha = 0;
  179. } completion:^(BOOL finished) {
  180. [progressView removeFromSuperview];
  181. [self removeCCMask];
  182. [self resetTitle];
  183. }];
  184. }];
  185. }
  186. - (void)showCCProgressWithDuration:(float)duration andTintColor:(UIColor *)tintColor
  187. {
  188. [[self progressView] setTintColor:tintColor];
  189. [self showCCProgressWithDuration:duration];
  190. }
  191. - (void)showCCProgressWithDuration:(float)duration andTintColor:(UIColor *)tintColor andTitle:(NSString *)title
  192. {
  193. [self changeCCProgressWithTitle:title];
  194. [self showCCProgressWithDuration:duration andTintColor:tintColor];
  195. }
  196. - (void)showCCProgressWithMaskAndDuration:(float)duration
  197. {
  198. [self setupCCProgressMask];
  199. [self showCCProgressWithDuration:duration];
  200. }
  201. - (void)showCCProgressWithMaskAndDuration:(float)duration andTitle:(NSString *) title
  202. {
  203. [self changeCCProgressWithTitle:title];
  204. [self showCCProgressWithMaskAndDuration:duration];
  205. }
  206. - (void)finishCCProgress
  207. {
  208. CCProgressView *progressView = [self progressView];
  209. [UIView animateWithDuration:0.1 animations:^{
  210. progressView.progress = 1;
  211. }];
  212. }
  213. - (void)cancelCCProgress
  214. {
  215. CCProgressView *progressView = [self progressView];
  216. [UIView animateWithDuration:0.5 animations:^{
  217. progressView.alpha = 0;
  218. } completion:^(BOOL finished) {
  219. [progressView removeFromSuperview];
  220. [self removeCCMask];
  221. [self resetTitle];
  222. }];
  223. }
  224. - (void)setCCProgressPercentage:(float)percentage
  225. {
  226. CCProgressView *progressView = [self progressView];
  227. [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
  228. progressView.progress = percentage / 100.f;
  229. } completion:^(BOOL finished) {
  230. if (percentage >= 100)
  231. {
  232. [UIView animateWithDuration:0.5 animations:^{
  233. progressView.alpha = 0;
  234. } completion:^(BOOL finished) {
  235. [progressView removeFromSuperview];
  236. [self removeCCMask];
  237. [self resetTitle];
  238. }];
  239. }
  240. }];
  241. }
  242. - (void)setCCProgressPercentage:(float)percentage andTitle:(NSString *)title
  243. {
  244. [self changeCCProgressWithTitle:title];
  245. [self setCCProgressPercentage:percentage];
  246. }
  247. - (void)setCCProgressPercentage:(float)percentage andTintColor:(UIColor *)tintColor
  248. {
  249. [[self progressView] setTintColor:tintColor];
  250. [self setCCProgressPercentage:percentage];
  251. }
  252. - (void)setCCProgressMaskWithPercentage:(float)percentage
  253. {
  254. [self setCCProgressPercentage:percentage];
  255. [self setupCCProgressMask];
  256. }
  257. - (void)setCCProgressMaskWithPercentage:(float)percentage andTitle:(NSString *)title
  258. {
  259. [self changeCCProgressWithTitle:title];
  260. [self setCCProgressMaskWithPercentage:percentage];
  261. }
  262. @end