2
0

DNImageFlowViewController.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. //
  2. // DNImageFlowViewController.m
  3. // ImagePicker
  4. //
  5. // Created by DingXiao on 15/2/11.
  6. // Copyright (c) 2015年 Dennis. All rights reserved.
  7. //
  8. #import "DNImageFlowViewController.h"
  9. #import "DNImagePickerController.h"
  10. #import "DNPhotoBrowser.h"
  11. #import "UIView+DNImagePicker.h"
  12. #import "UIColor+Hex.h"
  13. #import "DNAssetsViewCell.h"
  14. #import "DNSendButton.h"
  15. #import "DNImagePickerHelper.h"
  16. #import "DNAlbum.h"
  17. #import "DNAsset.h"
  18. #import "MBProgressHUD.h"
  19. #import <Photos/Photos.h>
  20. #import "UIView+Toast.h"
  21. static NSUInteger const kDNImageFlowMaxSeletedNumber = 9;
  22. @interface DNImageFlowViewController () <UICollectionViewDataSource, UICollectionViewDelegate, DNAssetsViewCellDelegate, DNPhotoBrowserDelegate>
  23. @property (nonatomic, strong) DNAlbum *album;
  24. @property (nonatomic, copy) NSString *albumIdentifier;
  25. @property (nonatomic, strong) UICollectionView *imageFlowCollectionView;
  26. @property (nonatomic, strong) DNSendButton *sendButton;
  27. @property (nonatomic, strong) NSMutableArray *assetsArray;
  28. @property (nonatomic, strong) NSMutableArray *selectedAssetsArray;
  29. @property (nonatomic, strong) UIActivityIndicatorView *indicatorView;
  30. @property (nonatomic, assign) BOOL isFullImage;
  31. @end
  32. static NSString* const dnAssetsViewCellReuseIdentifier = @"DNAssetsViewCell";
  33. @implementation DNImageFlowViewController
  34. - (instancetype)initWithAlbumIdentifier:(NSString *)albumIdentifier {
  35. self = [super init];
  36. if (self) {
  37. _assetsArray = [NSMutableArray array];
  38. _selectedAssetsArray = [NSMutableArray array];
  39. _albumIdentifier = albumIdentifier;
  40. }
  41. return self;
  42. }
  43. - (instancetype)initWithAblum:(DNAlbum *)album {
  44. self = [super init];
  45. if (self) {
  46. _assetsArray = [NSMutableArray array];
  47. _selectedAssetsArray = [NSMutableArray array];
  48. _album = album;
  49. }
  50. return self;
  51. }
  52. - (void)viewDidLoad {
  53. [super viewDidLoad];
  54. [self setupView];
  55. [self setupData];
  56. }
  57. - (void)viewWillAppear:(BOOL)animated {
  58. [super viewWillAppear:animated];
  59. self.navigationController.toolbarHidden = NO;
  60. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadData) name:DNImagePickerPhotoLibraryChangedNotification object:nil];
  61. }
  62. - (void)viewWillDisappear:(BOOL)animated {
  63. [super viewWillDisappear:animated];
  64. self.navigationController.toolbarHidden = YES;
  65. [[NSNotificationCenter defaultCenter] removeObserver:self];
  66. }
  67. - (void)setupData {
  68. if (!self.album && self.albumIdentifier.length > 0) {
  69. __weak typeof(self) wSelf = self;
  70. [DNImagePickerHelper requestCurrentAblumWithCompleteHandler:^(DNAlbum *album) {
  71. __strong typeof(wSelf) sSelf = wSelf;
  72. sSelf.album = album;
  73. sSelf.title = sSelf.album.albumTitle;
  74. [sSelf loadData];
  75. }];
  76. } else {
  77. self.title = self.album.albumTitle;
  78. [self loadData];
  79. }
  80. }
  81. - (void)setupView {
  82. self.view.backgroundColor = [UIColor whiteColor];
  83. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:WFCString(@"cancel") style:UIBarButtonItemStyleDone target:self action:@selector(cancelAction)];
  84. [self imageFlowCollectionView];
  85. UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:WFCString(@"preview")
  86. style:UIBarButtonItemStylePlain
  87. target:self
  88. action:@selector(previewAction)];
  89. [item1 setTintColor:[UIColor blackColor]];
  90. item1.enabled = NO;
  91. UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
  92. UIBarButtonItem *item3 = [[UIBarButtonItem alloc] initWithCustomView:self.sendButton];
  93. UIBarButtonItem *item4 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  94. // item4.width = -10;
  95. [self setToolbarItems:@[item1,item2,item3,item4] animated:NO];
  96. }
  97. - (void)loadData {
  98. if (!self.assetsArray.count) {
  99. [self.indicatorView startAnimating];
  100. }
  101. __weak typeof(self) wSelf = self;
  102. [DNImagePickerHelper fetchImageAssetsInAlbum:self.album completeHandler:^(NSArray<DNAsset *> * imageArray) {
  103. __strong typeof(wSelf) sSelf = wSelf;
  104. [sSelf.indicatorView stopAnimating];
  105. [sSelf.assetsArray removeAllObjects];
  106. [sSelf.assetsArray addObjectsFromArray:imageArray];
  107. [self.imageFlowCollectionView reloadData];
  108. [self scrollerToBottom:NO];
  109. }];
  110. }
  111. #pragma mark - helpmethods
  112. - (void)scrollerToBottom:(BOOL)animated {
  113. NSInteger rows = [self.imageFlowCollectionView numberOfItemsInSection:0] - 1;
  114. [self.imageFlowCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:rows inSection:0]
  115. atScrollPosition:UICollectionViewScrollPositionBottom
  116. animated:animated];
  117. }
  118. - (DNImagePickerController *)dnImagePickerController {
  119. if (!self.navigationController
  120. ||
  121. ![self.navigationController isKindOfClass:[DNImagePickerController class]])
  122. {
  123. NSAssert(false, @"check the navigation controller");
  124. }
  125. return (DNImagePickerController *)self.navigationController;
  126. }
  127. - (void)removeAssetsObject:(DNAsset *)asset {
  128. if ([self.selectedAssetsArray containsObject:asset]) {
  129. [self.selectedAssetsArray removeObject:asset];
  130. }
  131. }
  132. - (void)addAssetsObject:(DNAsset *)asset {
  133. [self.selectedAssetsArray addObject:asset];
  134. }
  135. #pragma mark - priviate methods
  136. - (void)sendImages {
  137. [DNImagePickerHelper saveAblumIdentifier:self.album.identifier];
  138. DNImagePickerController *imagePicker = [self dnImagePickerController];
  139. [self.navigationController dismissViewControllerAnimated:YES completion:nil];
  140. if ([imagePicker.imagePickerDelegate respondsToSelector:@selector(dnImagePickerController:sendImages:isFullImage:)]) {
  141. [imagePicker.imagePickerDelegate dnImagePickerController:imagePicker sendImages:self.selectedAssetsArray isFullImage:self.isFullImage];
  142. }
  143. }
  144. - (void)browserPhotoAsstes:(NSArray *)assets pageIndex:(NSInteger)page {
  145. DNPhotoBrowser *browser = [[DNPhotoBrowser alloc] initWithPhotos:assets
  146. currentIndex:page
  147. fullImage:self.isFullImage];
  148. browser.delegate = self;
  149. browser.hidesBottomBarWhenPushed = YES;
  150. [self.navigationController pushViewController:browser animated:YES];
  151. }
  152. - (BOOL)seletedAssets:(DNAsset *)asset {
  153. if ([self.selectedAssetsArray containsObject:asset]) {
  154. return NO;
  155. }
  156. UIBarButtonItem *firstItem = self.toolbarItems.firstObject;
  157. firstItem.enabled = YES;
  158. if (self.selectedAssetsArray.count >= kDNImageFlowMaxSeletedNumber) {
  159. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:WFCString(@"alertTitle")
  160. message:WFCString(@"alertContent")
  161. delegate:self
  162. cancelButtonTitle:WFCString(@"alertButton")
  163. otherButtonTitles:nil, nil];
  164. [alert show];
  165. return NO;
  166. } else {
  167. [self addAssetsObject:asset];
  168. self.sendButton.badgeValue = [NSString stringWithFormat:@"%@",@(self.selectedAssetsArray.count)];
  169. return YES;
  170. }
  171. }
  172. - (void)deseletedAssets:(DNAsset *)asset {
  173. [self removeAssetsObject:asset];
  174. self.sendButton.badgeValue = [NSString stringWithFormat:@"%@",@(self.selectedAssetsArray.count)];
  175. if (self.selectedAssetsArray.count < 1) {
  176. UIBarButtonItem *firstItem = self.toolbarItems.firstObject;
  177. firstItem.enabled = NO;
  178. }
  179. }
  180. #pragma mark - getter/setter
  181. - (UICollectionView *)imageFlowCollectionView {
  182. if (!_imageFlowCollectionView) {
  183. UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
  184. layout.minimumLineSpacing = 2.0;
  185. layout.minimumInteritemSpacing = 2.0;
  186. layout.scrollDirection = UICollectionViewScrollDirectionVertical;
  187. _imageFlowCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) collectionViewLayout:layout];
  188. _imageFlowCollectionView.backgroundColor = [UIColor clearColor];
  189. [_imageFlowCollectionView registerClass:[DNAssetsViewCell class] forCellWithReuseIdentifier:dnAssetsViewCellReuseIdentifier];
  190. _imageFlowCollectionView.alwaysBounceVertical = YES;
  191. _imageFlowCollectionView.delegate = self;
  192. _imageFlowCollectionView.dataSource = self;
  193. _imageFlowCollectionView.showsHorizontalScrollIndicator = YES;
  194. [self.view addSubview:_imageFlowCollectionView];
  195. }
  196. return _imageFlowCollectionView;
  197. }
  198. - (DNSendButton *)sendButton {
  199. if (!_sendButton) {
  200. _sendButton = [[DNSendButton alloc] initWithFrame:CGRectZero];
  201. [_sendButton addTaget:self action:@selector(sendButtonAction:)];
  202. }
  203. return _sendButton;
  204. }
  205. - (UIActivityIndicatorView *)indicatorView {
  206. if (!_indicatorView) {
  207. _indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
  208. _indicatorView.hidesWhenStopped = YES;
  209. _indicatorView.centerX = CGRectGetWidth(self.view.bounds)/2;
  210. _indicatorView.centerY = CGRectGetHeight(self.view.bounds)/2;
  211. [self.view addSubview:_indicatorView];
  212. }
  213. return _indicatorView;
  214. }
  215. #pragma mark - ui action
  216. - (void)backButtonAction {
  217. [self.navigationController popViewControllerAnimated:YES];
  218. }
  219. - (void)sendButtonAction:(id)sender {
  220. if (self.selectedAssetsArray.count > 0) {
  221. [self sendImages];
  222. }
  223. }
  224. - (void)previewAction {
  225. [self browserPhotoAsstes:self.selectedAssetsArray pageIndex:0];
  226. }
  227. - (void)cancelAction {
  228. DNImagePickerController *navController = [self dnImagePickerController];
  229. if (navController && [navController.imagePickerDelegate respondsToSelector:@selector(dnImagePickerControllerDidCancel:)]) {
  230. [navController.imagePickerDelegate dnImagePickerControllerDidCancel:navController];
  231. }
  232. }
  233. #pragma mark - DNAssetsViewCellDelegate
  234. - (void)didSelectItemAssetsViewCell:(DNAssetsViewCell *)assetsCell {
  235. assetsCell.isSelected = [self seletedAssets:assetsCell.asset];
  236. }
  237. - (void)didDeselectItemAssetsViewCell:(DNAssetsViewCell *)assetsCell {
  238. assetsCell.isSelected = NO;
  239. [self deseletedAssets:assetsCell.asset];
  240. }
  241. #pragma mark - UICollectionView delegate and Datasource
  242. - (NSInteger)collectionView:(UICollectionView *)collectionView
  243. numberOfItemsInSection:(NSInteger)section {
  244. return self.assetsArray.count;
  245. }
  246. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
  247. cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  248. DNAssetsViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:dnAssetsViewCellReuseIdentifier forIndexPath:indexPath];
  249. DNAsset *asset = self.assetsArray[indexPath.row];
  250. cell.delegate = self;
  251. [cell fillWithAsset:asset isSelected:[self.selectedAssetsArray containsObject:asset]];
  252. return cell;
  253. }
  254. - (void)collectionView:(UICollectionView *)collectionView
  255. didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  256. [self browserPhotoAsstes:self.assetsArray pageIndex:indexPath.row];
  257. }
  258. #define kSizeThumbnailCollectionView ([UIScreen mainScreen].bounds.size.width-10)/4
  259. #pragma mark - UICollectionViewDelegateFlowLayout
  260. - (CGSize)collectionView:(UICollectionView *)collectionView
  261. layout:(UICollectionViewLayout *)collectionViewLayout
  262. sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  263. CGSize size = CGSizeMake(kSizeThumbnailCollectionView, kSizeThumbnailCollectionView);
  264. return size;
  265. }
  266. - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
  267. layout:(UICollectionViewLayout*)collectionViewLayout
  268. insetForSectionAtIndex:(NSInteger)section {
  269. return UIEdgeInsetsMake(2, 2, 2, 2);
  270. }
  271. #pragma mark - DNPhotoBrowserDelegate
  272. - (void)sendImagesFromPhotobrowser:(DNPhotoBrowser *)photoBrowser currentAsset:(DNAsset *)asset {
  273. if (self.selectedAssetsArray.count <= 0) {
  274. [self seletedAssets:asset];
  275. [self.imageFlowCollectionView reloadData];
  276. }
  277. [self sendImages];
  278. }
  279. - (NSUInteger)seletedPhotosNumberInPhotoBrowser:(DNPhotoBrowser *)photoBrowser {
  280. return self.selectedAssetsArray.count;
  281. }
  282. - (BOOL)photoBrowser:(DNPhotoBrowser *)photoBrowser currentPhotoAssetIsSeleted:(DNAsset *)asset{
  283. return [self.selectedAssetsArray containsObject:asset];
  284. }
  285. - (BOOL)photoBrowser:(DNPhotoBrowser *)photoBrowser seletedAsset:(DNAsset *)asset {
  286. BOOL seleted = [self seletedAssets:asset];
  287. [self.imageFlowCollectionView reloadData];
  288. return seleted;
  289. }
  290. - (void)photoBrowser:(DNPhotoBrowser *)photoBrowser deseletedAsset:(DNAsset *)asset {
  291. [self deseletedAssets:asset];
  292. [self.imageFlowCollectionView reloadData];
  293. }
  294. - (void)photoBrowser:(DNPhotoBrowser *)photoBrowser seleteFullImage:(BOOL)fullImage {
  295. self.isFullImage = fullImage;
  296. }
  297. @end