ATMHudView.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*
  2. * ATMHudView.m
  3. * ATMHud
  4. *
  5. * Created by Marcel Müller on 2011-03-01.
  6. * Copyright (c) 2010-2011, Marcel Müller (atomcraft)
  7. * All rights reserved.
  8. *
  9. * https://github.com/atomton/ATMHud
  10. */
  11. #import "ATMHudView.h"
  12. #import "ATMTextLayer.h"
  13. #import "ATMProgressLayer.h"
  14. #import "ATMHud.h"
  15. #import <QuartzCore/QuartzCore.h>
  16. #import "ATMHudDelegate.h"
  17. #import "ATMHudQueueItem.h"
  18. @implementation ATMHudView
  19. @synthesize caption, image, activity, activityStyle, p;
  20. @synthesize showActivity;
  21. @synthesize progress;
  22. @synthesize targetBounds, captionRect, progressRect, activityRect, imageRect;
  23. @synthesize fixedSize, activitySize;
  24. @synthesize backgroundLayer, imageLayer, captionLayer, progressLayer;
  25. - (CGRect)sharpRect:(CGRect)rect {
  26. CGRect r = rect;
  27. r.origin.x = (int)r.origin.x;
  28. r.origin.y = (int)r.origin.y;
  29. return r;
  30. }
  31. - (CGPoint)sharpPoint:(CGPoint)point {
  32. CGPoint _p = point;
  33. _p.x = (int)_p.x;
  34. _p.y = (int)_p.y;
  35. return _p;
  36. }
  37. - (id)initWithFrame:(CGRect)frame andController:(ATMHud *)c {
  38. if ((self = [super initWithFrame:frame])) {
  39. self.p = c;
  40. self.backgroundColor = [UIColor clearColor];
  41. self.opaque = NO;
  42. self.alpha = 0.0;
  43. backgroundLayer = [[CALayer alloc] init];
  44. backgroundLayer.cornerRadius = 10;
  45. backgroundLayer.backgroundColor = [UIColor colorWithWhite:0.0 alpha:p.alpha].CGColor;
  46. [self.layer addSublayer:backgroundLayer];
  47. captionLayer = [[ATMTextLayer alloc] init];
  48. captionLayer.contentsScale = [[UIScreen mainScreen] scale];
  49. captionLayer.anchorPoint = CGPointMake(0, 0);
  50. [self.layer addSublayer:captionLayer];
  51. imageLayer = [[CALayer alloc] init];
  52. imageLayer.anchorPoint = CGPointMake(0, 0);
  53. [self.layer addSublayer:imageLayer];
  54. progressLayer = [[ATMProgressLayer alloc] init];
  55. progressLayer.contentsScale = [[UIScreen mainScreen] scale];
  56. progressLayer.anchorPoint = CGPointMake(0, 0);
  57. [self.layer addSublayer:progressLayer];
  58. activity = [[UIActivityIndicatorView alloc] init];
  59. activity.hidesWhenStopped = YES;
  60. [self addSubview:activity];
  61. self.layer.shadowColor = [UIColor blackColor].CGColor;
  62. self.layer.shadowRadius = 8.0;
  63. self.layer.shadowOffset = CGSizeMake(0.0, 3.0);
  64. self.layer.shadowOpacity = 0.4;
  65. progressRect = CGRectMake(0, 0, 210, 20);
  66. activityStyle = UIActivityIndicatorViewStyleWhite;
  67. activitySize = CGSizeMake(20, 20);
  68. }
  69. return self;
  70. }
  71. - (void)dealloc {
  72. // [caption release];
  73. // [image release];
  74. // [activity release];
  75. // [p release];
  76. //
  77. // [backgroundLayer release];
  78. // [imageLayer release];
  79. // [captionLayer release];
  80. // [progressLayer release];
  81. // [super dealloc];
  82. }
  83. - (void)setProgress:(CGFloat)_p {
  84. _p = MIN(MAX(0,_p),1);
  85. if (_p > 0 && _p < 0.08) _p = 0.08;
  86. if(_p == progress) return;
  87. progress = _p;
  88. }
  89. - (void)calculate {
  90. if (!caption || [caption isEqualToString:@""]) {
  91. activityRect = CGRectMake(p.margin, p.margin, activitySize.width, activitySize.height);
  92. targetBounds = CGRectMake(0, 0, p.margin*2+activitySize.width, p.margin*2+activitySize.height);
  93. } else {
  94. BOOL hasFixedSize = NO;
  95. // CGSize captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  96. CGSize captionSize = [caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  97. if (fixedSize.width > 0 & fixedSize.height > 0) {
  98. CGSize s = fixedSize;
  99. if (progress > 0 && (fixedSize.width < progressRect.size.width+p.margin*2)) {
  100. s.width = progressRect.size.width+p.margin*2;
  101. }
  102. hasFixedSize = YES;
  103. // captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(s.width-p.margin*2, 200) lineBreakMode:UILineBreakModeWordWrap];
  104. captionSize = [caption boundingRectWithSize:CGSizeMake(s.width-p.margin*2, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  105. targetBounds = CGRectMake(0, 0, s.width, s.height);
  106. }
  107. captionRect = CGRectZero;
  108. captionRect.size = captionSize;
  109. float adjustment = 0;
  110. CGFloat marginX = p.margin;
  111. CGFloat marginY = p.margin;
  112. if (!hasFixedSize) {
  113. if (p.accessoryPosition == ATMHudAccessoryPositionTop || p.accessoryPosition == ATMHudAccessoryPositionBottom) {
  114. if (progress > 0) {
  115. adjustment = p.padding+progressRect.size.height;
  116. if (captionSize.width+p.margin*2 < progressRect.size.width) {
  117. // captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(progressRect.size.width, 200) lineBreakMode:UILineBreakModeWordWrap];
  118. captionSize = [caption boundingRectWithSize:CGSizeMake(progressRect.size.width, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  119. captionRect.size = captionSize;
  120. targetBounds = CGRectMake(0, 0, progressRect.size.width+p.margin*2, captionSize.height+p.margin*2+adjustment);
  121. } else {
  122. targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment);
  123. }
  124. } else {
  125. if (image) {
  126. adjustment = p.padding+image.size.height;
  127. } else if (showActivity) {
  128. adjustment = p.padding+activitySize.height;
  129. }
  130. targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment);
  131. }
  132. } else if (p.accessoryPosition == ATMHudAccessoryPositionLeft || p.accessoryPosition == ATMHudAccessoryPositionRight) {
  133. if (image) {
  134. adjustment = p.padding+image.size.width;
  135. } else if (showActivity) {
  136. adjustment = p.padding+activitySize.height;
  137. }
  138. targetBounds = CGRectMake(0, 0, captionSize.width+p.margin*2+adjustment, captionSize.height+p.margin*2);
  139. }
  140. } else {
  141. if (p.accessoryPosition == ATMHudAccessoryPositionTop || p.accessoryPosition == ATMHudAccessoryPositionBottom) {
  142. if (progress > 0) {
  143. adjustment = p.padding+progressRect.size.height;
  144. if (captionSize.width+p.margin*2 < progressRect.size.width) {
  145. // captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(progressRect.size.width, 200) lineBreakMode:UILineBreakModeWordWrap];
  146. captionSize = [caption boundingRectWithSize:CGSizeMake(progressRect.size.width, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  147. captionRect.size = captionSize;
  148. }
  149. } else {
  150. if (image) {
  151. adjustment = p.padding+image.size.height;
  152. } else if (showActivity) {
  153. adjustment = p.padding+activitySize.height;
  154. }
  155. }
  156. int deltaWidth = targetBounds.size.width-captionSize.width;
  157. marginX = 0.5*deltaWidth;
  158. if (marginX < p.margin) {
  159. // captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  160. captionSize = [caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  161. captionRect.size = captionSize;
  162. targetBounds = CGRectMake(0, 0, captionSize.width+2*p.margin, targetBounds.size.height);
  163. marginX = p.margin;
  164. }
  165. int deltaHeight = targetBounds.size.height-(adjustment+captionSize.height);
  166. marginY = 0.5*deltaHeight;
  167. if (marginY < p.margin) {
  168. targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionSize.height+2*p.margin+adjustment);
  169. marginY = p.margin;
  170. }
  171. } else if (p.accessoryPosition == ATMHudAccessoryPositionLeft || p.accessoryPosition == ATMHudAccessoryPositionRight) {
  172. if (image) {
  173. adjustment = p.padding+image.size.width;
  174. } else if (showActivity) {
  175. adjustment = p.padding+activitySize.width;
  176. }
  177. int deltaWidth = targetBounds.size.width-(adjustment+captionSize.width);
  178. marginX = 0.5*deltaWidth;
  179. if (marginX < p.margin) {
  180. // captionSize = [caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  181. captionSize = [caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  182. captionRect.size = captionSize;
  183. targetBounds = CGRectMake(0, 0, adjustment+captionSize.width+2*p.margin, targetBounds.size.height);
  184. marginX = p.margin;
  185. }
  186. int deltaHeight = targetBounds.size.height-captionSize.height;
  187. marginY = 0.5*deltaHeight;
  188. if (marginY < p.margin) {
  189. targetBounds = CGRectMake(0, 0, targetBounds.size.width, captionSize.height+2*p.margin);
  190. marginY = p.margin;
  191. }
  192. }
  193. }
  194. switch (p.accessoryPosition) {
  195. case ATMHudAccessoryPositionTop: {
  196. activityRect = CGRectMake((targetBounds.size.width-activitySize.width)*0.5, marginY, activitySize.width, activitySize.height);
  197. imageRect = CGRectZero;
  198. imageRect.origin.x = (targetBounds.size.width-image.size.width)*0.5;
  199. imageRect.origin.y = marginY;
  200. imageRect.size = image.size;
  201. progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5, marginY, progressRect.size.width, progressRect.size.height);
  202. captionRect.origin.x = (targetBounds.size.width-captionSize.width)*0.5;
  203. captionRect.origin.y = adjustment+marginY;
  204. break;
  205. }
  206. case ATMHudAccessoryPositionRight: {
  207. activityRect = CGRectMake(marginX+p.padding+captionSize.width, (targetBounds.size.height-activitySize.height)*0.5, activitySize.width, activitySize.height);
  208. imageRect = CGRectZero;
  209. imageRect.origin.x = marginX+p.padding+captionSize.width;
  210. imageRect.origin.y = (targetBounds.size.height-image.size.height)*0.5;
  211. imageRect.size = image.size;
  212. captionRect.origin.x = marginX;
  213. captionRect.origin.y = marginY;
  214. break;
  215. }
  216. case ATMHudAccessoryPositionBottom: {
  217. activityRect = CGRectMake((targetBounds.size.width-activitySize.width)*0.5, captionRect.size.height+marginY+p.padding, activitySize.width, activitySize.height);
  218. imageRect = CGRectZero;
  219. imageRect.origin.x = (targetBounds.size.width-image.size.width)*0.5;
  220. imageRect.origin.y = captionRect.size.height+marginY+p.padding;
  221. imageRect.size = image.size;
  222. progressRect = CGRectMake((targetBounds.size.width-progressRect.size.width)*0.5, captionRect.size.height+marginY+p.padding, progressRect.size.width, progressRect.size.height);
  223. captionRect.origin.x = (targetBounds.size.width-captionSize.width)*0.5;
  224. captionRect.origin.y = marginY;
  225. break;
  226. }
  227. case ATMHudAccessoryPositionLeft: {
  228. activityRect = CGRectMake(marginX, (targetBounds.size.height-activitySize.height)*0.5, activitySize.width, activitySize.height);
  229. imageRect = CGRectZero;
  230. imageRect.origin.x = marginX;
  231. imageRect.origin.y = (targetBounds.size.height-image.size.height)*0.5;
  232. imageRect.size = image.size;
  233. captionRect.origin.x = marginX+adjustment;
  234. captionRect.origin.y = marginY;
  235. break;
  236. }
  237. }
  238. }
  239. }
  240. - (CGSize)sizeForActivityStyle:(UIActivityIndicatorViewStyle)style {
  241. if (style == UIActivityIndicatorViewStyleWhiteLarge) {
  242. return CGSizeMake(37, 37);
  243. } else {
  244. return CGSizeMake(20, 20);
  245. }
  246. }
  247. - (CGSize)calculateSizeForQueueItem:(ATMHudQueueItem *)item {
  248. CGSize targetSize = CGSizeZero;
  249. CGSize styleSize = [self sizeForActivityStyle:item.activityStyle];
  250. if (!item.caption || [item.caption isEqualToString:@""]) {
  251. targetSize = CGSizeMake(p.margin*2+styleSize.width, p.margin*2+styleSize.height);
  252. } else {
  253. BOOL hasFixedSize = NO;
  254. // CGSize captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  255. CGSize captionSize = [item.caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  256. float adjustment = 0;
  257. CGFloat marginX = 0;
  258. CGFloat marginY = 0;
  259. if (!hasFixedSize) {
  260. if (item.accessoryPosition == ATMHudAccessoryPositionTop || item.accessoryPosition == ATMHudAccessoryPositionBottom) {
  261. if (item.image) {
  262. adjustment = p.padding+item.image.size.height;
  263. } else if (item.showActivity) {
  264. adjustment = p.padding+styleSize.height;
  265. }
  266. targetSize = CGSizeMake(captionSize.width+p.margin*2, captionSize.height+p.margin*2+adjustment);
  267. } else if (item.accessoryPosition == ATMHudAccessoryPositionLeft || item.accessoryPosition == ATMHudAccessoryPositionRight) {
  268. if (item.image) {
  269. adjustment = p.padding+item.image.size.width;
  270. } else if (item.showActivity) {
  271. adjustment = p.padding+styleSize.width;
  272. }
  273. targetSize = CGSizeMake(captionSize.width+p.margin*2+adjustment, captionSize.height+p.margin*2);
  274. }
  275. } else {
  276. if (item.accessoryPosition == ATMHudAccessoryPositionTop || item.accessoryPosition == ATMHudAccessoryPositionBottom) {
  277. if (item.image) {
  278. adjustment = p.padding+item.image.size.height;
  279. } else if (item.showActivity) {
  280. adjustment = p.padding+styleSize.height;
  281. }
  282. int deltaWidth = targetSize.width-captionSize.width;
  283. marginX = 0.5*deltaWidth;
  284. if (marginX < p.margin) {
  285. // captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  286. captionSize = [item.caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  287. targetSize = CGSizeMake(captionSize.width+2*p.margin, targetSize.height);
  288. }
  289. int deltaHeight = targetSize.height-(adjustment+captionSize.height);
  290. marginY = 0.5*deltaHeight;
  291. if (marginY < p.margin) {
  292. targetSize = CGSizeMake(targetSize.width, captionSize.height+2*p.margin+adjustment);
  293. }
  294. } else if (item.accessoryPosition == ATMHudAccessoryPositionLeft || item.accessoryPosition == ATMHudAccessoryPositionRight) {
  295. if (item.image) {
  296. adjustment = p.padding+item.image.size.width;
  297. } else if (item.showActivity) {
  298. adjustment = p.padding+styleSize.width;
  299. }
  300. int deltaWidth = targetSize.width-(adjustment+captionSize.width);
  301. marginX = 0.5*deltaWidth;
  302. if (marginX < p.margin) {
  303. // captionSize = [item.caption sizeWithFont:[UIFont boldSystemFontOfSize:14] constrainedToSize:CGSizeMake(160, 200) lineBreakMode:UILineBreakModeWordWrap];
  304. captionSize = [item.caption boundingRectWithSize:CGSizeMake(160, 200) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]} context:nil].size;
  305. targetSize = CGSizeMake(adjustment+captionSize.width+2*p.margin, targetSize.height);
  306. }
  307. int deltaHeight = targetSize.height-captionSize.height;
  308. marginY = 0.5*deltaHeight;
  309. if (marginY < p.margin) {
  310. targetSize = CGSizeMake(targetSize.width, captionSize.height+2*p.margin);
  311. }
  312. }
  313. }
  314. }
  315. return targetSize;
  316. }
  317. - (void)applyWithMode:(ATMHudApplyMode)mode {
  318. switch (mode) {
  319. case ATMHudApplyModeShow: {
  320. if (CGPointEqualToPoint(p.center, CGPointZero)) {
  321. self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5, (self.superview.bounds.size.height-targetBounds.size.height)*0.5, targetBounds.size.width, targetBounds.size.height);
  322. } else {
  323. self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height);
  324. self.center = p.center;
  325. }
  326. [CATransaction begin];
  327. [CATransaction setDisableActions:YES];
  328. [CATransaction setCompletionBlock:^{
  329. if (showActivity) {
  330. activity.activityIndicatorViewStyle = activityStyle;
  331. activity.frame = [self sharpRect:activityRect];
  332. }
  333. CGRect r = self.frame;
  334. [self setFrame:[self sharpRect:r]];
  335. if ([(id)p.delegate respondsToSelector:@selector(hudWillAppear:)]) {
  336. [p.delegate hudWillAppear:p];
  337. }
  338. self.transform = CGAffineTransformMakeScale(p.appearScaleFactor, p.appearScaleFactor);
  339. [UIView animateWithDuration:.1
  340. animations:^{
  341. self.transform = CGAffineTransformMakeScale(1.0, 1.0);
  342. self.alpha = 1.0;
  343. }
  344. completion:^(BOOL finished){
  345. if (finished) {
  346. if (!p.allowSuperviewInteraction) {
  347. self.superview.userInteractionEnabled = YES;
  348. }
  349. if (![p.showSound isEqualToString:@""] && p.showSound != NULL) {
  350. [p playSound:p.showSound];
  351. }
  352. if ([(id)p.delegate respondsToSelector:@selector(hudDidAppear:)]) {
  353. [p.delegate hudDidAppear:p];
  354. }
  355. }
  356. }];
  357. }];
  358. backgroundLayer.position = CGPointMake(0.5*targetBounds.size.width, 0.5*targetBounds.size.height);
  359. backgroundLayer.bounds = targetBounds;
  360. captionLayer.position = [self sharpPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)];
  361. captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height);
  362. CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"];
  363. cAnimation.duration = 0.001;
  364. cAnimation.toValue = caption;
  365. [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"];
  366. captionLayer.caption = caption;
  367. imageLayer.contents = (id)image.CGImage;
  368. imageLayer.position = [self sharpPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)];
  369. imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height);
  370. progressLayer.position = [self sharpPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)];
  371. progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height);
  372. progressLayer.progressBorderRadius = p.progressBorderRadius;
  373. progressLayer.progressBorderWidth = p.progressBorderWidth;
  374. progressLayer.progressBarRadius = p.progressBarRadius;
  375. progressLayer.progressBarInset = p.progressBarInset;
  376. progressLayer.theProgress = progress;
  377. [progressLayer setNeedsDisplay];
  378. [CATransaction commit];
  379. break;
  380. }
  381. case ATMHudApplyModeUpdate: {
  382. if ([(id)p.delegate respondsToSelector:@selector(hudWillUpdate:)]) {
  383. [p.delegate hudWillUpdate:p];
  384. }
  385. if (CGPointEqualToPoint(p.center, CGPointZero)) {
  386. self.frame = CGRectMake((self.superview.bounds.size.width-targetBounds.size.width)*0.5, (self.superview.bounds.size.height-targetBounds.size.height)*0.5, targetBounds.size.width, targetBounds.size.height);
  387. } else {
  388. self.bounds = CGRectMake(0, 0, targetBounds.size.width, targetBounds.size.height);
  389. self.center = p.center;
  390. }
  391. CABasicAnimation *ccAnimation = [CABasicAnimation animationWithKeyPath:@"caption"];
  392. ccAnimation.duration = 0.001;
  393. ccAnimation.toValue = @"";
  394. ccAnimation.delegate = self;
  395. [captionLayer addAnimation:ccAnimation forKey:@"captionClearAnimation"];
  396. captionLayer.caption = @"";
  397. [CATransaction begin];
  398. [CATransaction setDisableActions:YES];
  399. [CATransaction setCompletionBlock:^{
  400. backgroundLayer.bounds = targetBounds;
  401. progressLayer.theProgress = progress;
  402. [progressLayer setNeedsDisplay];
  403. CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"];
  404. cAnimation.duration = 0.001;
  405. cAnimation.toValue = caption;
  406. [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"];
  407. captionLayer.caption = caption;
  408. if (showActivity) {
  409. activity.activityIndicatorViewStyle = activityStyle;
  410. activity.frame = [self sharpRect:activityRect];
  411. }
  412. CGRect r = self.frame;
  413. [self setFrame:[self sharpRect:r]];
  414. if (![p.updateSound isEqualToString:@""] && p.updateSound != NULL) {
  415. [p playSound:p.updateSound];
  416. }
  417. if ([(id)p.delegate respondsToSelector:@selector(hudDidUpdate:)]) {
  418. [p.delegate hudDidUpdate:p];
  419. }
  420. }];
  421. backgroundLayer.position = CGPointMake(0.5*targetBounds.size.width, 0.5*targetBounds.size.height);
  422. imageLayer.position = [self sharpPoint:CGPointMake(imageRect.origin.x, imageRect.origin.y)];
  423. progressLayer.position = [self sharpPoint:CGPointMake(progressRect.origin.x, progressRect.origin.y)];
  424. imageLayer.bounds = CGRectMake(0, 0, imageRect.size.width, imageRect.size.height);
  425. progressLayer.bounds = CGRectMake(0, 0, progressRect.size.width, progressRect.size.height);
  426. progressLayer.progressBorderRadius = p.progressBorderRadius;
  427. progressLayer.progressBorderWidth = p.progressBorderWidth;
  428. progressLayer.progressBarRadius = p.progressBarRadius;
  429. progressLayer.progressBarInset = p.progressBarInset;
  430. captionLayer.position = [self sharpPoint:CGPointMake(captionRect.origin.x, captionRect.origin.y)];
  431. captionLayer.bounds = CGRectMake(0, 0, captionRect.size.width, captionRect.size.height);
  432. imageLayer.contents = (id)image.CGImage;
  433. [CATransaction commit];
  434. break;
  435. }
  436. case ATMHudApplyModeHide: {
  437. if ([(id)p.delegate respondsToSelector:@selector(hudWillDisappear:)]) {
  438. [p.delegate hudWillDisappear:p];
  439. }
  440. if (![p.hideSound isEqualToString:@""] && p.hideSound != NULL) {
  441. [p playSound:p.hideSound];
  442. }
  443. [UIView animateWithDuration:.1
  444. animations:^{
  445. self.alpha = 0.0;
  446. self.transform = CGAffineTransformMakeScale(p.disappearScaleFactor, p.disappearScaleFactor);
  447. }
  448. completion:^(BOOL finished){
  449. if (finished) {
  450. self.superview.userInteractionEnabled = NO;
  451. self.transform = CGAffineTransformMakeScale(1.0, 1.0);
  452. [self reset];
  453. if ([(id)p.delegate respondsToSelector:@selector(hudDidDisappear:)]) {
  454. [p.delegate hudDidDisappear:p];
  455. }
  456. }
  457. }];
  458. break;
  459. }
  460. }
  461. }
  462. - (void)show {
  463. [self calculate];
  464. [self applyWithMode:ATMHudApplyModeShow];
  465. }
  466. - (void)hide {
  467. [self applyWithMode:ATMHudApplyModeHide];
  468. }
  469. - (void)update {
  470. [self calculate];
  471. [self applyWithMode:ATMHudApplyModeUpdate];
  472. }
  473. - (void)reset {
  474. [p setCaption:@""];
  475. [p setImage:nil];
  476. [p setProgress:0];
  477. [p setActivity:NO];
  478. [p setActivityStyle:UIActivityIndicatorViewStyleWhite];
  479. [p setAccessoryPosition:ATMHudAccessoryPositionBottom];
  480. [p setBlockTouches:NO];
  481. [p setAllowSuperviewInteraction:NO];
  482. // TODO: Reset or not reset, that is the question.
  483. [p setFixedSize:CGSizeZero];
  484. [p setCenter:CGPointZero];
  485. [CATransaction begin];
  486. [CATransaction setDisableActions:YES];
  487. imageLayer.contents = nil;
  488. [CATransaction commit];
  489. CABasicAnimation *cAnimation = [CABasicAnimation animationWithKeyPath:@"caption"];
  490. cAnimation.duration = 0.001;
  491. cAnimation.toValue = @"";
  492. [captionLayer addAnimation:cAnimation forKey:@"captionAnimation"];
  493. captionLayer.caption = @"";
  494. [p setShowSound:@""];
  495. [p setUpdateSound:@""];
  496. [p setHideSound:@""];
  497. }
  498. @end