2
0

MWGridCell.m 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //
  2. // MWGridCell.m
  3. // MWPhotoBrowser
  4. //
  5. // Created by Michael Waterfall on 08/10/2013.
  6. //
  7. //
  8. #import "DACircularProgressView.h"
  9. #import "MWGridCell.h"
  10. #import "MWCommon.h"
  11. #import "MWPhotoBrowserPrivate.h"
  12. #import "UIImage+MWPhotoBrowser.h"
  13. #define VIDEO_INDICATOR_PADDING 10
  14. @interface MWGridCell () {
  15. UIImageView *_imageView;
  16. UIImageView *_videoIndicator;
  17. UIImageView *_loadingError;
  18. DACircularProgressView *_loadingIndicator;
  19. UIButton *_selectedButton;
  20. }
  21. @end
  22. @implementation MWGridCell
  23. - (id)initWithFrame:(CGRect)frame {
  24. if ((self = [super initWithFrame:frame])) {
  25. // Grey background
  26. self.backgroundColor = [UIColor colorWithWhite:0.12 alpha:1];
  27. // Image
  28. _imageView = [UIImageView new];
  29. _imageView.frame = self.bounds;
  30. _imageView.contentMode = UIViewContentModeScaleAspectFill;
  31. _imageView.clipsToBounds = YES;
  32. _imageView.autoresizesSubviews = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  33. [self addSubview:_imageView];
  34. // Video Image
  35. _videoIndicator = [UIImageView new];
  36. _videoIndicator.hidden = NO;
  37. UIImage *videoIndicatorImage = [UIImage imageForResourcePath:@"MWPhotoBrowser.bundle/VideoOverlay" ofType:@"png" inBundle:[NSBundle bundleForClass:[self class]]];
  38. _videoIndicator.frame = CGRectMake(self.bounds.size.width - videoIndicatorImage.size.width - VIDEO_INDICATOR_PADDING, self.bounds.size.height - videoIndicatorImage.size.height - VIDEO_INDICATOR_PADDING, videoIndicatorImage.size.width, videoIndicatorImage.size.height);
  39. _videoIndicator.image = videoIndicatorImage;
  40. _videoIndicator.autoresizesSubviews = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
  41. [self addSubview:_videoIndicator];
  42. // Selection button
  43. _selectedButton = [UIButton buttonWithType:UIButtonTypeCustom];
  44. _selectedButton.contentMode = UIViewContentModeTopRight;
  45. _selectedButton.adjustsImageWhenHighlighted = NO;
  46. [_selectedButton setImage:[UIImage imageForResourcePath:@"MWPhotoBrowser.bundle/ImageSelectedSmallOff" ofType:@"png" inBundle:[NSBundle bundleForClass:[self class]]] forState:UIControlStateNormal];
  47. [_selectedButton setImage:[UIImage imageForResourcePath:@"MWPhotoBrowser.bundle/ImageSelectedSmallOn" ofType:@"png" inBundle:[NSBundle bundleForClass:[self class]]] forState:UIControlStateSelected];
  48. [_selectedButton addTarget:self action:@selector(selectionButtonPressed) forControlEvents:UIControlEventTouchDown];
  49. _selectedButton.hidden = YES;
  50. _selectedButton.frame = CGRectMake(0, 0, 44, 44);
  51. [self addSubview:_selectedButton];
  52. // Loading indicator
  53. _loadingIndicator = [[DACircularProgressView alloc] initWithFrame:CGRectMake(0, 0, 40.0f, 40.0f)];
  54. _loadingIndicator.userInteractionEnabled = NO;
  55. _loadingIndicator.thicknessRatio = 0.1;
  56. _loadingIndicator.roundedCorners = NO;
  57. [self addSubview:_loadingIndicator];
  58. // Listen for photo loading notifications
  59. [[NSNotificationCenter defaultCenter] addObserver:self
  60. selector:@selector(setProgressFromNotification:)
  61. name:MWPHOTO_PROGRESS_NOTIFICATION
  62. object:nil];
  63. [[NSNotificationCenter defaultCenter] addObserver:self
  64. selector:@selector(handleMWPhotoLoadingDidEndNotification:)
  65. name:MWPHOTO_LOADING_DID_END_NOTIFICATION
  66. object:nil];
  67. }
  68. return self;
  69. }
  70. - (void)dealloc {
  71. [[NSNotificationCenter defaultCenter] removeObserver:self];
  72. }
  73. - (void)setGridController:(MWGridViewController *)gridController {
  74. _gridController = gridController;
  75. // Set custom selection image if required
  76. if (_gridController.browser.customImageSelectedSmallIconName) {
  77. [_selectedButton setImage:[UIImage imageNamed:_gridController.browser.customImageSelectedSmallIconName] forState:UIControlStateSelected];
  78. }
  79. }
  80. #pragma mark - View
  81. - (void)layoutSubviews {
  82. [super layoutSubviews];
  83. _imageView.frame = self.bounds;
  84. _loadingIndicator.frame = CGRectMake(floorf((self.bounds.size.width - _loadingIndicator.frame.size.width) / 2.),
  85. floorf((self.bounds.size.height - _loadingIndicator.frame.size.height) / 2),
  86. _loadingIndicator.frame.size.width,
  87. _loadingIndicator.frame.size.height);
  88. _selectedButton.frame = CGRectMake(self.bounds.size.width - _selectedButton.frame.size.width - 0,
  89. 0, _selectedButton.frame.size.width, _selectedButton.frame.size.height);
  90. }
  91. #pragma mark - Cell
  92. - (void)prepareForReuse {
  93. _photo = nil;
  94. _gridController = nil;
  95. _imageView.image = nil;
  96. _loadingIndicator.progress = 0;
  97. _selectedButton.hidden = YES;
  98. [self hideImageFailure];
  99. [super prepareForReuse];
  100. }
  101. #pragma mark - Image Handling
  102. - (void)setPhoto:(id <MWPhoto>)photo {
  103. _photo = photo;
  104. if ([photo respondsToSelector:@selector(isVideo)]) {
  105. _videoIndicator.hidden = !photo.isVideo;
  106. } else {
  107. _videoIndicator.hidden = YES;
  108. }
  109. if (_photo) {
  110. if (![_photo underlyingImage]) {
  111. [self showLoadingIndicator];
  112. } else {
  113. [self hideLoadingIndicator];
  114. }
  115. } else {
  116. [self showImageFailure];
  117. }
  118. }
  119. - (void)displayImage {
  120. _imageView.image = [_photo underlyingImage];
  121. _selectedButton.hidden = !_selectionMode;
  122. [self hideImageFailure];
  123. }
  124. #pragma mark - Selection
  125. - (void)setSelectionMode:(BOOL)selectionMode {
  126. _selectionMode = selectionMode;
  127. }
  128. - (void)setIsSelected:(BOOL)isSelected {
  129. _isSelected = isSelected;
  130. _selectedButton.selected = isSelected;
  131. }
  132. - (void)selectionButtonPressed {
  133. _selectedButton.selected = !_selectedButton.selected;
  134. [_gridController.browser setPhotoSelected:_selectedButton.selected atIndex:_index];
  135. }
  136. #pragma mark - Touches
  137. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  138. _imageView.alpha = 0.6;
  139. [super touchesBegan:touches withEvent:event];
  140. }
  141. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  142. _imageView.alpha = 1;
  143. [super touchesEnded:touches withEvent:event];
  144. }
  145. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
  146. _imageView.alpha = 1;
  147. [super touchesCancelled:touches withEvent:event];
  148. }
  149. #pragma mark Indicators
  150. - (void)hideLoadingIndicator {
  151. _loadingIndicator.hidden = YES;
  152. }
  153. - (void)showLoadingIndicator {
  154. _loadingIndicator.progress = 0;
  155. _loadingIndicator.hidden = NO;
  156. [self hideImageFailure];
  157. }
  158. - (void)showImageFailure {
  159. // Only show if image is not empty
  160. if (![_photo respondsToSelector:@selector(emptyImage)] || !_photo.emptyImage) {
  161. if (!_loadingError) {
  162. _loadingError = [UIImageView new];
  163. _loadingError.image = [UIImage imageForResourcePath:@"MWPhotoBrowser.bundle/ImageError" ofType:@"png" inBundle:[NSBundle bundleForClass:[self class]]];
  164. _loadingError.userInteractionEnabled = NO;
  165. [_loadingError sizeToFit];
  166. [self addSubview:_loadingError];
  167. }
  168. _loadingError.frame = CGRectMake(floorf((self.bounds.size.width - _loadingError.frame.size.width) / 2.),
  169. floorf((self.bounds.size.height - _loadingError.frame.size.height) / 2),
  170. _loadingError.frame.size.width,
  171. _loadingError.frame.size.height);
  172. }
  173. [self hideLoadingIndicator];
  174. _imageView.image = nil;
  175. }
  176. - (void)hideImageFailure {
  177. if (_loadingError) {
  178. [_loadingError removeFromSuperview];
  179. _loadingError = nil;
  180. }
  181. }
  182. #pragma mark - Notifications
  183. - (void)setProgressFromNotification:(NSNotification *)notification {
  184. dispatch_async(dispatch_get_main_queue(), ^{
  185. NSDictionary *dict = [notification object];
  186. id <MWPhoto> photoWithProgress = [dict objectForKey:@"photo"];
  187. if (photoWithProgress == _photo) {
  188. // NSLog(@"%f", [[dict valueForKey:@"progress"] floatValue]);
  189. float progress = [[dict valueForKey:@"progress"] floatValue];
  190. _loadingIndicator.progress = MAX(MIN(1, progress), 0);
  191. }
  192. });
  193. }
  194. - (void)handleMWPhotoLoadingDidEndNotification:(NSNotification *)notification {
  195. id <MWPhoto> photo = [notification object];
  196. if (photo == _photo) {
  197. if ([photo underlyingImage]) {
  198. // Successful load
  199. [self displayImage];
  200. } else {
  201. // Failed to load
  202. [self showImageFailure];
  203. }
  204. [self hideLoadingIndicator];
  205. }
  206. }
  207. @end