HXPhotoSubViewCell.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //
  2. // HXPhotoSubViewCell.m
  3. // HXPhotoPickerExample
  4. //
  5. // Created by Silence on 17/2/17.
  6. // Copyright © 2017年 Silence. All rights reserved.
  7. //
  8. #import "HXPhotoSubViewCell.h"
  9. #import "HXPhotoModel.h"
  10. #import "HXCircleProgressView.h"
  11. #import "HXPhotoTools.h"
  12. #import "HXPhotoBottomSelectView.h"
  13. #import "HXPhotoEdit.h"
  14. #import "UIColor+HXExtension.h"
  15. #import "HXAssetManager.h"
  16. @interface HXPhotoSubViewCell ()
  17. @property (strong, nonatomic) UIImageView *imageView;
  18. @property (strong, nonatomic) UIButton *deleteBtn;
  19. @property (strong, nonatomic) HXCircleProgressView *progressView;
  20. @property (assign, nonatomic) PHImageRequestID requestID;
  21. @property (strong, nonatomic) UILabel *stateLb;
  22. @property (strong, nonatomic) CAGradientLayer *bottomMaskLayer;
  23. @property (strong, nonatomic) UIView *bottomMaskView;
  24. @property (assign, nonatomic) BOOL addCustomViewCompletion;
  25. @property (strong, nonatomic) UIView *customView;
  26. @end
  27. @implementation HXPhotoSubViewCell
  28. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  29. [super traitCollectionDidChange:previousTraitCollection];
  30. #ifdef __IPHONE_13_0
  31. if (@available(iOS 13.0, *)) {
  32. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  33. if (self.model.type == HXPhotoModelMediaTypeCamera) {
  34. if ([HXPhotoCommon photoCommon].isDark) {
  35. self.imageView.image = self.model.previewPhoto;
  36. }else {
  37. self.imageView.image = self.model.thumbPhoto;
  38. }
  39. }
  40. }
  41. }
  42. #endif
  43. }
  44. - (instancetype)initWithFrame:(CGRect)frame {
  45. self = [super initWithFrame:frame];
  46. if (self) {
  47. [self setup];
  48. }
  49. return self;
  50. }
  51. #pragma mark - < 懒加载 >
  52. - (UIImageView *)imageView {
  53. if (!_imageView) {
  54. _imageView = [[UIImageView alloc] init];
  55. _imageView.clipsToBounds = YES;
  56. _imageView.contentMode = UIViewContentModeScaleAspectFill;
  57. }
  58. return _imageView;
  59. }
  60. - (UILabel *)stateLb {
  61. if (!_stateLb) {
  62. _stateLb = [[UILabel alloc] init];
  63. _stateLb.textColor = [UIColor whiteColor];
  64. _stateLb.textAlignment = NSTextAlignmentRight;
  65. _stateLb.font = [UIFont hx_mediumSFUITextOfSize:12];
  66. }
  67. return _stateLb;
  68. }
  69. - (UIView *)bottomMaskView {
  70. if (!_bottomMaskView) {
  71. _bottomMaskView = [[UIView alloc] init];
  72. [_bottomMaskView.layer addSublayer:self.bottomMaskLayer];
  73. }
  74. return _bottomMaskView;
  75. }
  76. - (CAGradientLayer *)bottomMaskLayer {
  77. if (!_bottomMaskLayer) {
  78. _bottomMaskLayer = [CAGradientLayer layer];
  79. _bottomMaskLayer.colors = @[
  80. (id)[[UIColor blackColor] colorWithAlphaComponent:0].CGColor ,
  81. (id)[[UIColor blackColor] colorWithAlphaComponent:0.15].CGColor ,
  82. (id)[[UIColor blackColor] colorWithAlphaComponent:0.35].CGColor ,
  83. (id)[[UIColor blackColor] colorWithAlphaComponent:0.6].CGColor
  84. ];
  85. _bottomMaskLayer.startPoint = CGPointMake(0, 0);
  86. _bottomMaskLayer.endPoint = CGPointMake(0, 1);
  87. _bottomMaskLayer.locations = @[@(0.15f),@(0.35f),@(0.6f),@(0.9f)];
  88. _bottomMaskLayer.borderWidth = 0.0;
  89. }
  90. return _bottomMaskLayer;
  91. }
  92. - (UIButton *)deleteBtn {
  93. if (!_deleteBtn) {
  94. _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  95. [_deleteBtn setImage:[UIImage hx_imageNamed:@"hx_compose_delete"] forState:UIControlStateNormal];
  96. [_deleteBtn addTarget:self action:@selector(didDeleteClick) forControlEvents:UIControlEventTouchUpInside];
  97. }
  98. return _deleteBtn;
  99. }
  100. - (HXCircleProgressView *)progressView {
  101. if (!_progressView) {
  102. _progressView = [[HXCircleProgressView alloc] init];
  103. _progressView.hidden = YES;
  104. }
  105. return _progressView;
  106. }
  107. - (void)setup {
  108. [self.contentView addSubview:self.imageView];
  109. [self.contentView addSubview:self.bottomMaskView];
  110. [self.contentView addSubview:self.stateLb];
  111. [self.contentView addSubview:self.deleteBtn];
  112. [self.contentView addSubview:self.progressView];
  113. [self.contentView addSubview:self.highlightMaskView];
  114. }
  115. - (void)didDeleteClick {
  116. BOOL showAlert = NO;
  117. NSString *title;
  118. if (self.deleteCellShowAlert) {
  119. showAlert = YES;
  120. if (self.model.subType == HXPhotoModelMediaSubTypePhoto) {
  121. title = [NSBundle hx_localizedStringForKey:@"要删除这张照片吗?"];
  122. }else if (self.model.subType == HXPhotoModelMediaSubTypeVideo) {
  123. title = [NSBundle hx_localizedStringForKey:@"要删除此视频吗?"];
  124. }
  125. }else {
  126. if (self.model.networkPhotoUrl) {
  127. if (self.showDeleteNetworkPhotoAlert) {
  128. showAlert = YES;
  129. title = [NSBundle hx_localizedStringForKey:@"是否删除此资源"];
  130. }
  131. }
  132. }
  133. if (showAlert) {
  134. HXPhotoBottomViewModel *titleModel = [[HXPhotoBottomViewModel alloc] init];
  135. titleModel.title = title ?: @"";
  136. titleModel.titleFont = [UIFont systemFontOfSize:13];
  137. titleModel.titleColor = [UIColor hx_colorWithHexStr:@"#666666"];
  138. titleModel.titleDarkColor = [UIColor hx_colorWithHexStr:@"#999999"];
  139. titleModel.cellHeight = 60.f;
  140. titleModel.canSelect = NO;
  141. HXPhotoBottomViewModel *deleteModel = [[HXPhotoBottomViewModel alloc] init];
  142. deleteModel.title = [NSBundle hx_localizedStringForKey:@"删除"];
  143. deleteModel.titleColor = [UIColor redColor];
  144. deleteModel.titleDarkColor = [[UIColor redColor] colorWithAlphaComponent:0.8f];
  145. HXWeakSelf
  146. [HXPhotoBottomSelectView showSelectViewWithModels:@[titleModel, deleteModel] selectCompletion:^(NSInteger index, HXPhotoBottomViewModel * _Nonnull model) {
  147. if ([weakSelf.delegate respondsToSelector:@selector(cellDidDeleteClcik:)]) {
  148. [weakSelf.delegate cellDidDeleteClcik:weakSelf];
  149. }
  150. } cancelClick:nil];
  151. return;
  152. }
  153. #if HasYYWebImage
  154. // [self.imageView yy_cancelCurrentImageRequest];
  155. #elif HasYYKit
  156. // [self.imageView cancelCurrentImageRequest];
  157. #elif HasSDWebImage
  158. // [self.imageView sd_cancelCurrentAnimationImagesLoad];
  159. #endif
  160. if ([self.delegate respondsToSelector:@selector(cellDidDeleteClcik:)]) {
  161. [self.delegate cellDidDeleteClcik:self];
  162. }
  163. }
  164. - (void)againDownload {
  165. self.model.downloadError = NO;
  166. self.model.downloadComplete = NO;
  167. HXWeakSelf
  168. [self.imageView hx_setImageWithModel:self.model original:NO progress:^(CGFloat progress, HXPhotoModel *model) {
  169. if (weakSelf.model == model) {
  170. weakSelf.progressView.progress = progress;
  171. }
  172. } completed:^(UIImage *image, NSError *error, HXPhotoModel *model) {
  173. if (weakSelf.model == model) {
  174. if (error != nil) {
  175. weakSelf.model.downloadError = YES;
  176. weakSelf.model.downloadComplete = YES;
  177. [weakSelf.progressView showError];
  178. }else {
  179. if (image) {
  180. weakSelf.progressView.progress = 1;
  181. weakSelf.progressView.hidden = YES;
  182. weakSelf.imageView.image = image;
  183. weakSelf.userInteractionEnabled = YES;
  184. }
  185. }
  186. }
  187. }];
  188. }
  189. - (void)setHideDeleteButton:(BOOL)hideDeleteButton {
  190. _hideDeleteButton = hideDeleteButton;
  191. if (self.model.type != HXPhotoModelMediaTypeCamera) {
  192. self.deleteBtn.hidden = hideDeleteButton;
  193. }
  194. }
  195. - (void)setDeleteImageName:(NSString *)deleteImageName {
  196. _deleteImageName = deleteImageName;
  197. [self.deleteBtn setImage:[UIImage hx_imageNamed:deleteImageName] forState:UIControlStateNormal];
  198. }
  199. - (void)resetNetworkImage {
  200. if (self.model.networkPhotoUrl &&
  201. (self.model.type == HXPhotoModelMediaTypeCameraPhoto ||
  202. self.model.cameraVideoType == HXPhotoModelMediaTypeCameraVideoTypeNetWork)) {
  203. self.model.loadOriginalImage = YES;
  204. self.model.previewViewSize = CGSizeZero;
  205. self.model.endImageSize = CGSizeZero;
  206. HXWeakSelf
  207. [self.imageView hx_setImageWithModel:self.model original:YES progress:nil completed:^(UIImage *image, NSError *error, HXPhotoModel *model) {
  208. if (weakSelf.model == model) {
  209. if (image.images.count) {
  210. weakSelf.imageView.image = nil;
  211. weakSelf.imageView.image = image.images.firstObject;
  212. }else {
  213. weakSelf.imageView.image = image;
  214. }
  215. }
  216. }];
  217. }
  218. }
  219. - (void)setModel:(HXPhotoModel *)model {
  220. _model = model;
  221. self.progressView.hidden = YES;
  222. self.progressView.progress = 0;
  223. self.imageView.image = nil;
  224. if (model.type == HXPhotoModelMediaTypeCamera) {
  225. self.deleteBtn.hidden = YES;
  226. if ([HXPhotoCommon photoCommon].isDark) {
  227. self.imageView.image = model.previewPhoto;
  228. }else {
  229. self.imageView.image = model.thumbPhoto;
  230. }
  231. }else {
  232. if (model.localIdentifier && !model.asset) {
  233. model.asset = [HXAssetManager fetchAssetWithLocalIdentifier:model.localIdentifier];
  234. }
  235. self.deleteBtn.hidden = NO;
  236. if (model.networkPhotoUrl) {
  237. if (model.photoEdit) {
  238. self.imageView.image = model.photoEdit.editPreviewImage;
  239. }else {
  240. HXWeakSelf
  241. if (model.downloadComplete && !model.downloadError) {
  242. if (model.previewPhoto.images.count) {
  243. self.imageView.image = nil;
  244. self.imageView.image = model.previewPhoto.images.firstObject;
  245. }else {
  246. self.imageView.image = model.previewPhoto;
  247. }
  248. }else {
  249. self.progressView.hidden = NO;
  250. [self.imageView hx_setImageWithModel:model original:NO progress:^(CGFloat progress, HXPhotoModel *model) {
  251. if (weakSelf.model == model) {
  252. weakSelf.progressView.progress = progress;
  253. }
  254. } completed:^(UIImage *image, NSError *error, HXPhotoModel *model) {
  255. if (weakSelf.model == model) {
  256. if (error != nil) {
  257. [weakSelf.progressView showError];
  258. }else {
  259. if (image) {
  260. weakSelf.progressView.progress = 1;
  261. weakSelf.progressView.hidden = YES;
  262. if (image.images.count) {
  263. weakSelf.imageView.image = nil;
  264. weakSelf.imageView.image = image.images.firstObject;
  265. }else {
  266. weakSelf.imageView.image = image;
  267. }
  268. }
  269. }
  270. }
  271. }];
  272. }
  273. }
  274. }else {
  275. if (model.photoEdit) {
  276. self.imageView.image = model.photoEdit.editPreviewImage;
  277. }else {
  278. if (model.asset) {
  279. HXWeakSelf
  280. PHImageRequestID requestID = [self.model requestThumbImageWithWidth:250 completion:^(UIImage *image, HXPhotoModel *model, NSDictionary *info) {
  281. if (weakSelf.model == model) {
  282. weakSelf.imageView.image = image;
  283. }
  284. }];
  285. if (self.requestID != requestID) {
  286. [[PHImageManager defaultManager] cancelImageRequest:self.requestID];
  287. }
  288. self.requestID = requestID;
  289. }else {
  290. if (model.previewPhoto) {
  291. if (model.previewPhoto.images.count) {
  292. self.imageView.image = nil;
  293. self.imageView.image = model.previewPhoto.images.firstObject;
  294. }else {
  295. self.imageView.image = model.previewPhoto;
  296. }
  297. }else if (model.thumbPhoto) {
  298. if (model.thumbPhoto.images.count) {
  299. self.imageView.image = nil;
  300. self.imageView.image = model.thumbPhoto.images.firstObject;
  301. }else {
  302. self.imageView.image = model.thumbPhoto;
  303. }
  304. }
  305. }
  306. }
  307. }
  308. }
  309. if (self.customProtocol) {
  310. [CATransaction begin];
  311. [CATransaction setDisableActions:YES];
  312. }
  313. if (model.type == HXPhotoModelMediaTypePhotoGif && !model.photoEdit) {
  314. self.stateLb.text = @"GIF";
  315. self.stateLb.hidden = NO;
  316. self.bottomMaskView.hidden = NO;
  317. }else if (model.type == HXPhotoModelMediaTypeLivePhoto && !model.photoEdit) {
  318. self.stateLb.text = @"Live";
  319. self.stateLb.hidden = NO;
  320. self.bottomMaskView.hidden = NO;
  321. }else {
  322. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  323. self.stateLb.text = model.videoTime;
  324. self.stateLb.hidden = NO;
  325. self.bottomMaskView.hidden = NO;
  326. }else {
  327. if ((model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeNetWorkGif ||
  328. model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeLocalGif) && !model.photoEdit) {
  329. self.stateLb.text = @"GIF";
  330. self.stateLb.hidden = NO;
  331. self.bottomMaskView.hidden = NO;
  332. return;
  333. }else if ((model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeLocalLivePhoto ||
  334. model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeNetWorkLivePhoto) &&
  335. !model.photoEdit) {
  336. self.stateLb.text = @"Live";
  337. self.stateLb.hidden = NO;
  338. self.bottomMaskView.hidden = NO;
  339. return;
  340. }
  341. self.stateLb.hidden = YES;
  342. self.bottomMaskView.hidden = YES;
  343. }
  344. }
  345. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.index inSection:0];
  346. if ([self.customProtocol respondsToSelector:@selector(customView:indexPath:)]) {
  347. if (!self.addCustomViewCompletion) {
  348. UIView *customView = [self.customProtocol customView:self indexPath:indexPath];
  349. if (customView) {
  350. [self.contentView addSubview:customView];
  351. }
  352. self.customView = customView;
  353. self.addCustomViewCompletion = YES;
  354. }
  355. }
  356. if ([self.customProtocol respondsToSelector:@selector(setCustomViewData:cell:model:indexPath:)]) {
  357. [self.customProtocol setCustomViewData:self.customView cell:self model:model indexPath:indexPath];
  358. }
  359. if ([self.customProtocol respondsToSelector:@selector(shouldHiddenBottomType:indexPath:)]) {
  360. BOOL hiddenState = [self.customProtocol shouldHiddenBottomType:self indexPath:indexPath];
  361. if (hiddenState) {
  362. self.stateLb.hidden = hiddenState;
  363. self.bottomMaskView.hidden = hiddenState;
  364. }
  365. }
  366. if ([self.customProtocol respondsToSelector:@selector(customViewFrame:indexPath:)]) {
  367. CGRect customViewFrame = [self.customProtocol customViewFrame:self indexPath:indexPath];
  368. self.customView.frame = customViewFrame;
  369. }
  370. if ([self.customProtocol respondsToSelector:@selector(customDeleteButtonFrame:indexPath:)]) {
  371. CGRect deleteFrame = [self.customProtocol customDeleteButtonFrame:self indexPath:indexPath];
  372. self.deleteBtn.frame = deleteFrame;
  373. }
  374. if (self.customProtocol) {
  375. [CATransaction commit];
  376. }
  377. }
  378. - (void)layoutSubviews
  379. {
  380. [super layoutSubviews];
  381. self.imageView.frame = self.bounds;
  382. self.stateLb.frame = CGRectMake(0, self.hx_h - 18, self.hx_w - 4, 18);
  383. self.bottomMaskView.frame = CGRectMake(0, self.hx_h - 25, self.hx_w, 25);
  384. self.bottomMaskLayer.frame = self.bottomMaskView.bounds;
  385. CGFloat width = self.frame.size.width;
  386. CGFloat height = self.frame.size.height;
  387. if (![self.customProtocol respondsToSelector:@selector(customDeleteButtonFrame:indexPath:)]) {
  388. CGFloat deleteBtnW = self.deleteBtn.currentImage.size.width;
  389. CGFloat deleteBtnH = self.deleteBtn.currentImage.size.height;
  390. self.deleteBtn.frame = CGRectMake(width - deleteBtnW, 0, deleteBtnW, deleteBtnH);
  391. }
  392. self.progressView.center = CGPointMake(width / 2, height / 2);
  393. self.highlightMaskView.frame = self.bounds;
  394. }
  395. - (void)setHighlighted:(BOOL)highlighted {
  396. [super setHighlighted:highlighted];
  397. if (self.model.type == HXPhotoModelMediaTypeCamera || self.canEdit) {
  398. return;
  399. }
  400. self.highlightMaskView.hidden = !highlighted;
  401. }
  402. - (UIView *)highlightMaskView {
  403. if (!_highlightMaskView) {
  404. _highlightMaskView = [[UIView alloc] init];
  405. _highlightMaskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
  406. _highlightMaskView.hidden = YES;
  407. }
  408. return _highlightMaskView;
  409. }
  410. @end