PhotoPreviewViewController.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. //
  2. // PhotoPreviewViewController.m
  3. // 隐私保护
  4. //
  5. // Created by xd h on 2023/11/11.
  6. //
  7. #import "PhotoPreviewViewController.h"
  8. #import "TZPhotoPreviewCell.h"
  9. #import "photoPreViewBottomView.h"
  10. #import "uploadFileRecordViewController.h"
  11. @interface PhotoPreviewViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,UIScrollViewDelegate>
  12. @property (strong, nonatomic) UIButton *selectButton;
  13. @property (strong, nonatomic) UICollectionView *photoPreviewCollectionV;
  14. @property (strong, nonatomic) photoPreViewBottomView *photoPreViewBottomV;
  15. @property (assign, nonatomic) BOOL canSetCurrentIndex;//
  16. @property (strong, nonatomic)TZVideoPreviewCell * curCell;
  17. @property (assign, nonatomic) BOOL didChangeSelectIndexType;//是否重新选择过
  18. @end
  19. @implementation PhotoPreviewViewController
  20. - (void)viewDidLoad {
  21. [super viewDidLoad];
  22. // Do any additional setup after loading the view.
  23. [self.view setBackgroundColor:[UIColor blackColor]];
  24. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoPreviewCellDidPlayerFun) name:@"TZ_VIDEO_PLAY_NOTIFICATION" object:nil];
  25. [self.toolBar setHidden:YES];
  26. [self.navigationBar setHidden:YES];
  27. [self.navBarBGView setHidden:NO];
  28. [self setupPhotoPreviewNavBarView];
  29. //列表view
  30. [self setupPhotoPreviewCollectionView];
  31. [self setupPhotoPreViewBottomView];
  32. }
  33. - (void)viewWillAppear:(BOOL)animated
  34. {
  35. [super viewWillAppear: animated];
  36. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
  37. //[self.photoPreviewCollectionV reloadData];
  38. if (_currentIndex >= 0) {
  39. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  40. self->_canSetCurrentIndex = YES;
  41. [self.photoPreviewCollectionV setContentOffset:CGPointMake(SCREEN_W * self.currentIndex, 0) animated:NO];
  42. });
  43. }
  44. [self refreshNaviBarAndBottomBarState];
  45. }
  46. - (void)viewWillDisappear:(BOOL)animated
  47. {
  48. [super viewWillDisappear:animated];
  49. ///黑色
  50. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
  51. [UIApplication sharedApplication].statusBarHidden = NO;
  52. [self.curCell pausePlayerAndShowNaviBar];
  53. }
  54. - (void)backBtnPressed{
  55. [super backBtnPressed];
  56. if(_changeSelectIndex && _didChangeSelectIndexType){
  57. _changeSelectIndex(_indexPathsForSelectedItems);
  58. }
  59. }
  60. #pragma mark 点击选中按钮
  61. - (void)didClickButtonFun:(UIButton*)but
  62. {
  63. but.selected = !but.selected;
  64. [self handlCellSelectFun];
  65. _didChangeSelectIndexType = YES;
  66. }
  67. #pragma mark 处理点击选中相关
  68. - (void)handlCellSelectFun
  69. {
  70. TZAssetModel *model = self.assets[_currentIndex];
  71. //超出最大限制
  72. // if (self.indexPathsForSelectedItems.count >= self.maximumNumberOfSelection ) {
  73. // return;
  74. // }
  75. //取消选中
  76. if ([self.indexPathsForSelectedItems containsObject:model]) {
  77. [self.indexPathsForSelectedItems removeObject:model];
  78. model.isSelected = NO;
  79. }
  80. else{//选中
  81. [self.indexPathsForSelectedItems addObject:model];
  82. model.isSelected = YES;
  83. if(!model.imageData)
  84. {
  85. PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
  86. options.networkAccessAllowed = YES; // Allow downloading from iCloud
  87. options.version = PHImageRequestOptionsVersionCurrent;
  88. options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
  89. [[PHImageManager defaultManager] requestImageDataForAsset:model.asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
  90. // 直接得到最终的 NSData 数据
  91. if (imageData) {
  92. //model.imageData = imageData;
  93. model.totalBytes = [imageData length];
  94. }
  95. if(model.type != TZAssetModelMediaTypeVideo){
  96. [self setDataToBottomViewFun];
  97. }
  98. }];
  99. if(model.type == TZAssetModelMediaTypeVideo){
  100. PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
  101. options.version = PHVideoRequestOptionsVersionOriginal;
  102. options.networkAccessAllowed = YES; // Allow downloading from iCloud
  103. [[PHImageManager defaultManager] requestAVAssetForVideo:model.asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
  104. if ([asset isKindOfClass:[AVURLAsset class]]) {
  105. AVURLAsset* urlAsset = (AVURLAsset*)asset;
  106. //NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL];
  107. NSNumber *size;
  108. [urlAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
  109. //NSLog(@"size is %f",[size floatValue]/(1024.0*1024.0));
  110. //model.videoData = videoData;
  111. //model.totalBytes = [videoData length];
  112. model.totalBytes = size.longLongValue;
  113. [self setDataToBottomViewFun];
  114. }
  115. }];
  116. }
  117. }
  118. }
  119. [self setDataToBottomViewFun];
  120. //[self refreshNaviBarAndBottomBarState];
  121. }
  122. #pragma mark 同步数据到底部
  123. - (void)setDataToBottomViewFun
  124. {
  125. mainBlock(^{
  126. self.photoPreViewBottomV.indexPathsForSelectedItems = self.indexPathsForSelectedItems;
  127. });
  128. }
  129. #pragma mark 刷新导航栏的UI
  130. - (void)refreshNaviBarAndBottomBarState
  131. {
  132. self.titleLabel.text = [[NSString alloc] initWithFormat:@"%ld/%ld",(_currentIndex+1),_assets.count];
  133. TZAssetModel *model = self.assets[_currentIndex];
  134. self.selectButton.selected = model.isSelected;
  135. }
  136. - (void)setupPhotoPreviewNavBarView
  137. {
  138. [self.backBtn setImage:[UIImage imageNamed:@"icon_white_back"] forState:UIControlStateNormal];
  139. self.navBarBGView.backgroundColor = [UIColor blackColor];
  140. self.titleLabel.textColor = [UIColor whiteColor];
  141. UIButton *but = [[UIButton alloc] init];
  142. [but setImage:[UIImage imageNamed:@"upload_file_uncheck"] forState:UIControlStateNormal];
  143. [but setImage:[UIImage imageNamed:@"upload_file_check"] forState:UIControlStateSelected];
  144. [but addTarget:self action:@selector(didClickButtonFun:) forControlEvents:UIControlEventTouchUpInside];
  145. [self.navBarBGView addSubview:but];
  146. self.selectButton = but;
  147. [but mas_makeConstraints:^(MASConstraintMaker *make) {
  148. make.right.mas_equalTo(-15);
  149. make.width.mas_equalTo(40);
  150. make.height.mas_equalTo(40);
  151. make.centerY.equalTo(self.titleLabel.mas_centerY).offset(0.f);
  152. }];
  153. }
  154. - (void)setupPhotoPreviewCollectionView
  155. {
  156. UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
  157. [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
  158. UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
  159. collectionView.dataSource = self;
  160. collectionView.delegate = self;
  161. collectionView.translatesAutoresizingMaskIntoConstraints = NO;
  162. collectionView.pagingEnabled = YES;
  163. collectionView.showsVerticalScrollIndicator = NO;
  164. collectionView.showsHorizontalScrollIndicator = NO;
  165. [self.view insertSubview:collectionView atIndex:0];
  166. collectionView.backgroundColor = [UIColor blackColor];
  167. [collectionView registerClass:[TZPhotoPreviewCell class] forCellWithReuseIdentifier:@"TZPhotoPreviewCell"];
  168. [collectionView registerClass:[TZPhotoPreviewCell class] forCellWithReuseIdentifier:@"TZPhotoPreviewCellGIF"];
  169. [collectionView registerClass:[TZVideoPreviewCell class] forCellWithReuseIdentifier:@"TZVideoPreviewCell"];
  170. [collectionView registerClass:[TZGifPreviewCell class] forCellWithReuseIdentifier:@"TZGifPreviewCell"];
  171. self.photoPreviewCollectionV = collectionView;
  172. [collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
  173. make.left.mas_equalTo(0);
  174. make.right.mas_equalTo(0);
  175. make.bottom.mas_equalTo(-(60 + safeArea));
  176. make.top.equalTo(self.navBarBGView.mas_bottom).offset(0.f);
  177. }];
  178. }
  179. - (void)setupPhotoPreViewBottomView
  180. {
  181. photoPreViewBottomView * bottomView = [[photoPreViewBottomView alloc] init];
  182. [self.view addSubview:bottomView];
  183. self.photoPreViewBottomV = bottomView;
  184. NSString * uploadDefaultPath = [HWDataManager getStringWithKey:stringKeyAddSn(Const_photo_upload_default_path)];
  185. BOOL isExtraFileType = NO;
  186. BOOL isExtraPathFind = NO;
  187. if(uploadDefaultPath){
  188. if(![uploadDefaultPath containsString:@"sdcard/"]){
  189. isExtraFileType = YES;
  190. }
  191. }
  192. if(uploadDefaultPath && ksharedAppDelegate.cloudPhoneExtraFileListMod){
  193. NSArray*arr = ksharedAppDelegate.cloudPhoneExtraFileListMod.data;
  194. for (cloudPhoneExtraFileModel*model in arr) {
  195. if([uploadDefaultPath containsString:model.extraPath]){
  196. NSString * availableStorage = @"";
  197. NSInteger totalSize_k = model.extraAvableSize / 1024;
  198. if(totalSize_k < 1024){
  199. availableStorage = [[NSString alloc] initWithFormat:@"%ldKB",totalSize_k];
  200. }
  201. else if( totalSize_k >= 1024 && totalSize_k < 1024*1024){
  202. availableStorage = [[NSString alloc] initWithFormat:@"%.2fMB",totalSize_k/1024.0];
  203. }
  204. else{
  205. availableStorage = [[NSString alloc] initWithFormat:@"%.2fG",totalSize_k/1024.0/1024.0];
  206. }
  207. self.photoPreViewBottomV.availableStorage = availableStorage;
  208. //self.photoPreViewBottomV.available = model.extraAvableSize;
  209. isExtraPathFind = YES;
  210. break;
  211. }
  212. }
  213. }
  214. if(!isExtraFileType){
  215. self.photoPreViewBottomV.availableStorage = _availableStorage;
  216. //self.photoPreViewBottomV.available = baseInfoModel.data.available;
  217. }
  218. if(isExtraFileType && !isExtraPathFind){
  219. self.photoPreViewBottomV.isExtraFileAndNotFindPathType = YES;
  220. }
  221. else{
  222. self.photoPreViewBottomV.isExtraFileAndNotFindPathType = NO;
  223. }
  224. //self.photoPreViewBottomV.availableStorage = _availableStorage;
  225. [self setDataToBottomViewFun];
  226. [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  227. make.left.mas_equalTo(0);
  228. make.right.mas_equalTo(0);
  229. make.bottom.mas_equalTo(0);
  230. make.height.mas_equalTo((60 + safeArea));
  231. }];
  232. KWeakSelf
  233. bottomView.didClickUploadFile = ^{
  234. [weakSelf gotoUploadFileRecordFun];
  235. };
  236. }
  237. #pragma mark - UIScrollViewDelegate
  238. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  239. CGFloat offSetWidth = scrollView.contentOffset.x;
  240. offSetWidth = offSetWidth + (SCREEN_W * 0.5);
  241. //NSInteger currentIndex = offSetWidth / (SCREEN_W + 20);
  242. NSInteger currentIndex = offSetWidth / (SCREEN_W);
  243. if (currentIndex < _assets.count && _currentIndex != currentIndex && _canSetCurrentIndex)
  244. {
  245. _currentIndex = currentIndex;
  246. [self refreshNaviBarAndBottomBarState];
  247. }
  248. [[NSNotificationCenter defaultCenter] postNotificationName:@"photoPreviewCollectionViewDidScroll" object:nil];
  249. }
  250. #pragma mark - uicollectionDelegate
  251. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  252. return self.assets.count;
  253. }
  254. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  255. TZAssetModel *model = self.assets[indexPath.row];
  256. TZAssetPreviewCell *cell;
  257. __weak typeof(self) weakSelf = self;
  258. if (model.type == TZAssetModelMediaTypeVideo) {
  259. cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZVideoPreviewCell" forIndexPath:indexPath];
  260. TZVideoPreviewCell *currentCell = (TZVideoPreviewCell *)cell;
  261. currentCell.iCloudSyncFailedHandle = ^(id asset, BOOL isSyncFailed) {
  262. model.iCloudFailed = isSyncFailed;
  263. //[weakSelf didICloudSyncStatusChanged:model];
  264. };
  265. } else if (model.type == TZAssetModelMediaTypePhotoGif) {
  266. cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZGifPreviewCell" forIndexPath:indexPath];
  267. TZGifPreviewCell *currentCell = (TZGifPreviewCell *)cell;
  268. currentCell.previewView.iCloudSyncFailedHandle = ^(id asset, BOOL isSyncFailed) {
  269. model.iCloudFailed = isSyncFailed;
  270. //[weakSelf didICloudSyncStatusChanged:model];
  271. };
  272. } else {
  273. NSString *reuseId = model.type == TZAssetModelMediaTypePhotoGif ? @"TZPhotoPreviewCellGIF" : @"TZPhotoPreviewCell";
  274. cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseId forIndexPath:indexPath];
  275. TZPhotoPreviewCell *photoPreviewCell = (TZPhotoPreviewCell *)cell;
  276. //photoPreviewCell.cropRect = _tzImagePickerVc.cropRect;
  277. //photoPreviewCell.allowCrop = _tzImagePickerVc.allowCrop;
  278. //photoPreviewCell.scaleAspectFillCrop = _tzImagePickerVc.scaleAspectFillCrop;
  279. // __weak typeof(_collectionView) weakCollectionView = _collectionView;
  280. // __weak typeof(photoPreviewCell) weakCell = photoPreviewCell;
  281. // [photoPreviewCell setImageProgressUpdateBlock:^(double progress) {
  282. // __strong typeof(weakSelf) strongSelf = weakSelf;
  283. // __strong typeof(weakCollectionView) strongCollectionView = weakCollectionView;
  284. // __strong typeof(weakCell) strongCell = weakCell;
  285. // strongSelf.progress = progress;
  286. // if (progress >= 1) {
  287. // if (strongSelf.isSelectOriginalPhoto) [strongSelf showPhotoBytes];
  288. // if (strongSelf.alertView && [strongCollectionView.visibleCells containsObject:strongCell]) {
  289. // [strongSelf.alertView dismissViewControllerAnimated:YES completion:^{
  290. // strongSelf.alertView = nil;
  291. // [strongSelf doneButtonClick];
  292. // }];
  293. // }
  294. // }
  295. // }];
  296. photoPreviewCell.previewView.iCloudSyncFailedHandle = ^(id asset, BOOL isSyncFailed) {
  297. model.iCloudFailed = isSyncFailed;
  298. //[weakSelf didICloudSyncStatusChanged:model];
  299. };
  300. }
  301. cell.model = model;
  302. // [cell setSingleTapGestureBlock:^{
  303. // __strong typeof(weakSelf) strongSelf = weakSelf;
  304. // //[strongSelf didTapPreviewCell];
  305. //
  306. // if([cell isKindOfClass:[TZVideoPreviewCell class]]){
  307. // weakSelf.curCell = cell;
  308. // }
  309. //
  310. // }];
  311. return cell;
  312. }
  313. - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
  314. return UIEdgeInsetsMake(0, 0, 0, 0);
  315. }
  316. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  317. CGFloat wh = SCREEN_H - CGRectGetMaxY(self.navBarBGView.frame) - (60 + safeArea);
  318. return CGSizeMake(SCREEN_W, wh);
  319. }
  320. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  321. return 0.0;
  322. }
  323. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  324. return 0.0;
  325. }
  326. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
  327. }
  328. #pragma mark 跳转上传记录
  329. - (void)gotoUploadFileRecordFun
  330. {
  331. [UIApplication sharedApplication].statusBarHidden = NO;
  332. uploadFileRecordViewController *vc = [uploadFileRecordViewController new];
  333. [self.navigationController pushViewController:vc animated:YES];
  334. vc.isUploadingType = YES;
  335. [vc gotoUploadFile:_indexPathsForSelectedItems];
  336. if(_isPhotoType){
  337. //数据埋点
  338. [[netWorkManager shareInstance] DataEmbeddingPointBy:3 withEventValue:@"Image_upload"];
  339. }
  340. else{
  341. //数据埋点
  342. [[netWorkManager shareInstance] DataEmbeddingPointBy:3 withEventValue:@"Video_upload"];
  343. }
  344. }
  345. #pragma mark TZVideoPreviewCell视频播放
  346. - (void)videoPreviewCellDidPlayerFun
  347. {
  348. //[UIApplication sharedApplication].statusBarHidden = NO;
  349. }
  350. @end