MWGridViewController.m 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //
  2. // MWGridViewController.m
  3. // MWPhotoBrowser
  4. //
  5. // Created by Michael Waterfall on 08/10/2013.
  6. //
  7. //
  8. #import "MWGridViewController.h"
  9. #import "MWGridCell.h"
  10. #import "MWPhotoBrowserPrivate.h"
  11. #import "MWCommon.h"
  12. @interface MWGridViewController () {
  13. // Store margins for current setup
  14. CGFloat _margin, _gutter, _marginL, _gutterL, _columns, _columnsL;
  15. }
  16. @end
  17. @implementation MWGridViewController
  18. - (id)init {
  19. if ((self = [super initWithCollectionViewLayout:[PSTCollectionViewFlowLayout new]])) {
  20. // Defaults
  21. _columns = 3, _columnsL = 4;
  22. _margin = 0, _gutter = 1;
  23. _marginL = 0, _gutterL = 1;
  24. // For pixel perfection...
  25. if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  26. // iPad
  27. _columns = 6, _columnsL = 8;
  28. _margin = 1, _gutter = 2;
  29. _marginL = 1, _gutterL = 2;
  30. } else if ([UIScreen mainScreen].bounds.size.height == 480) {
  31. // iPhone 3.5 inch
  32. _columns = 3, _columnsL = 4;
  33. _margin = 0, _gutter = 1;
  34. _marginL = 1, _gutterL = 2;
  35. } else {
  36. // iPhone 4 inch
  37. _columns = 3, _columnsL = 5;
  38. _margin = 0, _gutter = 1;
  39. _marginL = 0, _gutterL = 2;
  40. }
  41. _initialContentOffset = CGPointMake(0, CGFLOAT_MAX);
  42. }
  43. return self;
  44. }
  45. #pragma mark - View
  46. - (void)viewDidLoad {
  47. [super viewDidLoad];
  48. [self.collectionView registerClass:[MWGridCell class] forCellWithReuseIdentifier:@"GridCell"];
  49. self.collectionView.alwaysBounceVertical = YES;
  50. self.collectionView.backgroundColor = [UIColor blackColor];
  51. }
  52. - (void)viewWillDisappear:(BOOL)animated {
  53. // Cancel outstanding loading
  54. NSArray *visibleCells = [self.collectionView visibleCells];
  55. if (visibleCells) {
  56. for (MWGridCell *cell in visibleCells) {
  57. [cell.photo cancelAnyLoading];
  58. }
  59. }
  60. [super viewWillDisappear:animated];
  61. }
  62. - (void)viewWillLayoutSubviews {
  63. [super viewWillLayoutSubviews];
  64. [self performLayout];
  65. }
  66. - (void)viewDidLayoutSubviews {
  67. [super viewDidLayoutSubviews];
  68. // Move to previous content offset
  69. if (_initialContentOffset.y != CGFLOAT_MAX) {
  70. self.collectionView.contentOffset = _initialContentOffset;
  71. }
  72. CGPoint currentContentOffset = self.collectionView.contentOffset;
  73. // Get scroll position to have the current photo on screen
  74. if (_browser.numberOfPhotos > 0) {
  75. NSIndexPath *currentPhotoIndexPath = [NSIndexPath indexPathForItem:_browser.currentIndex inSection:0];
  76. [self.collectionView scrollToItemAtIndexPath:currentPhotoIndexPath atScrollPosition:PSTCollectionViewScrollPositionNone animated:NO];
  77. }
  78. CGPoint offsetToShowCurrent = self.collectionView.contentOffset;
  79. // Only commit to using the scrolled position if it differs from the initial content offset
  80. if (!CGPointEqualToPoint(offsetToShowCurrent, currentContentOffset)) {
  81. // Use offset to show current
  82. self.collectionView.contentOffset = offsetToShowCurrent;
  83. } else {
  84. // Stick with initial
  85. self.collectionView.contentOffset = currentContentOffset;
  86. }
  87. }
  88. - (void)performLayout {
  89. UINavigationBar *navBar = self.navigationController.navigationBar;
  90. CGFloat yAdjust = 0;
  91. #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
  92. if (SYSTEM_VERSION_LESS_THAN(@"7") && !self.browser.wantsFullScreenLayout) yAdjust = -20;
  93. #endif
  94. self.collectionView.contentInset = UIEdgeInsetsMake(navBar.frame.origin.y + navBar.frame.size.height + [self getGutter] + yAdjust, 0, 0, 0);
  95. }
  96. - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  97. [self.collectionView reloadData];
  98. [self performLayout]; // needed for iOS 5 & 6
  99. }
  100. #pragma mark - Layout
  101. - (CGFloat)getColumns {
  102. if ((UIInterfaceOrientationIsPortrait(self.interfaceOrientation))) {
  103. return _columns;
  104. } else {
  105. return _columnsL;
  106. }
  107. }
  108. - (CGFloat)getMargin {
  109. if ((UIInterfaceOrientationIsPortrait(self.interfaceOrientation))) {
  110. return _margin;
  111. } else {
  112. return _marginL;
  113. }
  114. }
  115. - (CGFloat)getGutter {
  116. if ((UIInterfaceOrientationIsPortrait(self.interfaceOrientation))) {
  117. return _gutter;
  118. } else {
  119. return _gutterL;
  120. }
  121. }
  122. #pragma mark - Collection View
  123. - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
  124. return [_browser numberOfPhotos];
  125. }
  126. - (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  127. MWGridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"GridCell" forIndexPath:indexPath];
  128. if (!cell) {
  129. cell = [[MWGridCell alloc] init];
  130. }
  131. id <MWPhoto> photo = [_browser thumbPhotoAtIndex:indexPath.row];
  132. cell.photo = photo;
  133. cell.gridController = self;
  134. cell.selectionMode = _selectionMode;
  135. cell.isSelected = [_browser photoIsSelectedAtIndex:indexPath.row];
  136. cell.index = indexPath.row;
  137. UIImage *img = [_browser imageForPhoto:photo];
  138. if (img) {
  139. [cell displayImage];
  140. } else {
  141. [photo loadUnderlyingImageAndNotify];
  142. }
  143. return cell;
  144. }
  145. - (void)collectionView:(PSTCollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  146. [_browser setCurrentPhotoIndex:indexPath.row];
  147. [_browser hideGrid];
  148. }
  149. - (void)collectionView:(PSTCollectionView *)collectionView didEndDisplayingCell:(PSTCollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
  150. [((MWGridCell *)cell).photo cancelAnyLoading];
  151. }
  152. - (CGSize)collectionView:(PSTCollectionView *)collectionView layout:(PSTCollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  153. CGFloat margin = [self getMargin];
  154. CGFloat gutter = [self getGutter];
  155. CGFloat columns = [self getColumns];
  156. CGFloat value = floorf(((self.view.bounds.size.width - (columns - 1) * gutter - 2 * margin) / columns));
  157. return CGSizeMake(value, value);
  158. }
  159. - (CGFloat)collectionView:(PSTCollectionView *)collectionView layout:(PSTCollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  160. return [self getGutter];
  161. }
  162. - (CGFloat)collectionView:(PSTCollectionView *)collectionView layout:(PSTCollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  163. return [self getGutter];
  164. }
  165. - (UIEdgeInsets)collectionView:(PSTCollectionView *)collectionView layout:(PSTCollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
  166. CGFloat margin = [self getMargin];
  167. return UIEdgeInsetsMake(margin, margin, margin, margin);
  168. }
  169. @end