HXPhotoViewController.m 160 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599
  1. //
  2. // HXPhotoViewController.m
  3. // HXPhotoPickerExample
  4. //
  5. // Created by Silence on 2017/10/14.
  6. // Copyright © 2017年 Silence. All rights reserved.
  7. //
  8. #import "HXPhotoViewController.h"
  9. #import "UIImage+HXExtension.h"
  10. #import "HXPhoto3DTouchViewController.h"
  11. #import "HXPhotoPreviewViewController.h"
  12. #import "UIButton+HXExtension.h"
  13. #import "HXCustomCameraViewController.h"
  14. #import "HXCustomNavigationController.h"
  15. #import "HXCustomCameraController.h"
  16. #import "HXCustomPreviewView.h"
  17. #import "HXPhotoEditViewController.h"
  18. #import "HXPhotoViewFlowLayout.h"
  19. #import "HXCircleProgressView.h"
  20. #import "UIViewController+HXExtension.h"
  21. #import "UIImageView+HXExtension.h"
  22. #if __has_include(<SDWebImage/UIImageView+WebCache.h>)
  23. #import <SDWebImage/UIImageView+WebCache.h>
  24. #elif __has_include("UIImageView+WebCache.h")
  25. #import "UIImageView+WebCache.h"
  26. #endif
  27. #import "HXAlbumlistView.h"
  28. #import "NSArray+HXExtension.h"
  29. #import "HXVideoEditViewController.h"
  30. #import "HXPhotoEdit.h"
  31. #import "HX_PhotoEditViewController.h"
  32. #import "UIColor+HXExtension.h"
  33. #import "HXAssetManager.h"
  34. @interface HXPhotoViewController ()
  35. <
  36. UICollectionViewDataSource,
  37. UICollectionViewDelegate,
  38. UICollectionViewDelegateFlowLayout,
  39. UIViewControllerPreviewingDelegate,
  40. HXPhotoViewCellDelegate,
  41. HXPhotoBottomViewDelegate,
  42. HXPhotoPreviewViewControllerDelegate,
  43. HXCustomCameraViewControllerDelegate,
  44. HXPhotoEditViewControllerDelegate,
  45. HXVideoEditViewControllerDelegate,
  46. HX_PhotoEditViewControllerDelegate
  47. //PHPhotoLibraryChangeObserver
  48. >
  49. @property (strong, nonatomic) UICollectionViewFlowLayout *flowLayout;
  50. @property (strong, nonatomic) UICollectionView *collectionView;
  51. @property (strong, nonatomic) NSMutableArray *allArray;
  52. @property (assign, nonatomic) NSInteger photoCount;
  53. @property (assign, nonatomic) NSInteger videoCount;
  54. @property (strong, nonatomic) NSMutableArray *previewArray;
  55. @property (strong, nonatomic) NSMutableArray *dateArray;
  56. @property (weak, nonatomic) id<UIViewControllerPreviewing> previewingContext;
  57. @property (assign, nonatomic) BOOL orientationDidChange;
  58. @property (assign, nonatomic) BOOL needChangeViewFrame;
  59. @property (strong, nonatomic) NSIndexPath *beforeOrientationIndexPath;
  60. @property (weak, nonatomic) HXPhotoViewSectionFooterView *footerView;
  61. @property (assign, nonatomic) BOOL showBottomPhotoCount;
  62. @property (strong, nonatomic) HXAlbumTitleView *albumTitleView;
  63. @property (strong, nonatomic) HXAlbumlistView *albumView;
  64. @property (strong, nonatomic) UIView *albumBgView;
  65. @property (strong, nonatomic) UILabel *authorizationLb;
  66. @property (assign, nonatomic) BOOL firstDidAlbumTitleView;
  67. @property (assign, nonatomic) BOOL collectionViewReloadCompletion;
  68. @property (weak, nonatomic) HXPhotoCameraViewCell *cameraCell;
  69. @property (assign, nonatomic) BOOL cellCanSetModel;
  70. @property (copy, nonatomic) NSArray *collectionVisibleCells;
  71. @property (assign, nonatomic) BOOL isNewEditDismiss;
  72. @property (assign, nonatomic) BOOL firstOn;
  73. @property (assign, nonatomic) BOOL assetDidChanged;
  74. @property (assign, nonatomic) CGPoint panSelectStartPoint;
  75. @property (strong, nonatomic) NSMutableArray *panSelectIndexPaths;
  76. @property (assign, nonatomic) NSInteger currentPanSelectType;
  77. @property (strong, nonatomic) HXHUD *imagePromptView;
  78. @end
  79. @implementation HXPhotoViewController
  80. #pragma mark - < life cycle >
  81. - (void)dealloc {
  82. if (_collectionView) {
  83. [self.collectionView.layer removeAllAnimations];
  84. }
  85. if (self.manager.configuration.open3DTouchPreview) {
  86. if (self.previewingContext) {
  87. if (@available(iOS 9.0, *)) {
  88. [self unregisterForPreviewingWithContext:self.previewingContext];
  89. }
  90. }
  91. }
  92. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
  93. }
  94. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  95. [super traitCollectionDidChange:previousTraitCollection];
  96. #ifdef __IPHONE_13_0
  97. if (@available(iOS 13.0, *)) {
  98. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  99. [self changeColor];
  100. [self changeStatusBarStyle];
  101. [self setNeedsStatusBarAppearanceUpdate];
  102. UIColor *authorizationColor = self.manager.configuration.authorizationTipColor;
  103. _authorizationLb.textColor = [HXPhotoCommon photoCommon].isDark ? [UIColor whiteColor] : authorizationColor;
  104. }
  105. }
  106. #endif
  107. }
  108. - (UIStatusBarStyle)preferredStatusBarStyle {
  109. if ([HXPhotoCommon photoCommon].isDark) {
  110. return UIStatusBarStyleLightContent;
  111. }
  112. return self.manager.configuration.statusBarStyle;
  113. }
  114. - (BOOL)prefersStatusBarHidden {
  115. return NO;
  116. }
  117. - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
  118. return UIStatusBarAnimationFade;
  119. }
  120. - (void)viewWillAppear:(BOOL)animated {
  121. [super viewWillAppear:animated];
  122. [self changeStatusBarStyle];
  123. #pragma clang diagnostic push
  124. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  125. [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
  126. #pragma clang diagnostic pop
  127. if (self.needChangeViewFrame) {
  128. self.needChangeViewFrame = NO;
  129. }
  130. if (self.manager.viewWillAppear) {
  131. self.manager.viewWillAppear(self);
  132. }
  133. }
  134. - (void)viewDidAppear:(BOOL)animated {
  135. [super viewDidAppear:animated];
  136. if (self.manager.configuration.cameraCellShowPreview) {
  137. if (!self.cameraCell.startSession) {
  138. [self.cameraCell starRunning];
  139. }
  140. }
  141. if (self.manager.viewDidAppear) {
  142. self.manager.viewDidAppear(self);
  143. }
  144. }
  145. - (void)viewWillDisappear:(BOOL)animated {
  146. [super viewWillDisappear:animated];
  147. if (self.manager.viewWillDisappear) {
  148. self.manager.viewWillDisappear(self);
  149. }
  150. }
  151. - (void)viewDidDisappear:(BOOL)animated {
  152. [super viewDidDisappear:animated];
  153. if (self.manager.viewDidDisappear) {
  154. self.manager.viewDidDisappear(self);
  155. }
  156. }
  157. #pragma clang diagnostic push
  158. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  159. - (void)changeStatusBarStyle {
  160. if ([HXPhotoCommon photoCommon].isDark) {
  161. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
  162. return;
  163. }
  164. [[UIApplication sharedApplication] setStatusBarStyle:self.manager.configuration.statusBarStyle animated:YES];
  165. }
  166. #pragma clang diagnostic pop
  167. - (void)viewDidLayoutSubviews {
  168. [super viewDidLayoutSubviews];
  169. if (self.orientationDidChange) {
  170. [self changeSubviewFrame];
  171. self.orientationDidChange = NO;
  172. }
  173. }
  174. - (void)viewDidLoad {
  175. [super viewDidLoad];
  176. self.assetDidChanged = NO;
  177. self.firstOn = YES;
  178. self.cellCanSetModel = YES;
  179. self.extendedLayoutIncludesOpaqueBars = YES;
  180. self.edgesForExtendedLayout = UIRectEdgeAll;
  181. if (self.manager.configuration.showBottomPhotoDetail) {
  182. self.showBottomPhotoCount = YES;
  183. self.manager.configuration.showBottomPhotoDetail = NO;
  184. }
  185. [self setupUI];
  186. [self changeSubviewFrame];
  187. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModeDefault) {
  188. [self getPhotoList];
  189. }else if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  190. [self authorizationHandler];
  191. HXWeakSelf
  192. self.hx_customNavigationController.reloadAsset = ^(BOOL initialAuthorization){
  193. if (initialAuthorization == YES) {
  194. if (weakSelf.manager.configuration.navigationBar) {
  195. weakSelf.manager.configuration.navigationBar(weakSelf.navigationController.navigationBar, weakSelf);
  196. }
  197. [weakSelf authorizationHandler];
  198. }else {
  199. if (weakSelf.albumTitleView.selected) {
  200. [weakSelf.albumTitleView deSelect];
  201. }
  202. [weakSelf.hx_customNavigationController.view hx_showLoadingHUDText:nil];
  203. weakSelf.collectionViewReloadCompletion = NO;
  204. weakSelf.albumTitleView.canSelect = YES;
  205. [weakSelf getAlbumList];
  206. }
  207. };
  208. }
  209. [self setupOtherConfiguration];
  210. }
  211. - (void)authorizationHandler {
  212. PHAuthorizationStatus status = [HXPhotoTools authorizationStatus];
  213. if (status == PHAuthorizationStatusAuthorized) {
  214. [self getAlbumList];
  215. }
  216. #ifdef __IPHONE_14_0
  217. else if (@available(iOS 14, *)) {
  218. if (status == PHAuthorizationStatusLimited) {
  219. [self getAlbumList];
  220. return;
  221. }
  222. #endif
  223. else if (status == PHAuthorizationStatusDenied ||
  224. status == PHAuthorizationStatusRestricted) {
  225. [self.hx_customNavigationController.view hx_handleLoading:NO];
  226. [self.view addSubview:self.authorizationLb];
  227. [HXPhotoTools showNoAuthorizedAlertWithViewController:self status:status];
  228. }
  229. #ifdef __IPHONE_14_0
  230. }else if (status == PHAuthorizationStatusDenied ||
  231. status == PHAuthorizationStatusRestricted) {
  232. [self.hx_customNavigationController.view hx_handleLoading:NO];
  233. [self.view addSubview:self.authorizationLb];
  234. [HXPhotoTools showNoAuthorizedAlertWithViewController:self status:status];
  235. }
  236. #endif
  237. }
  238. - (void)setupOtherConfiguration {
  239. if (self.manager.configuration.open3DTouchPreview) {
  240. //#ifdef __IPHONE_13_0
  241. // if (@available(iOS 13.0, *)) {
  242. // [HXPhotoCommon photoCommon].isHapticTouch = YES;
  243. //#else
  244. // if ((NO)) {
  245. //#endif
  246. // }else {
  247. if ([self respondsToSelector:@selector(traitCollection)]) {
  248. if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)]) {
  249. if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
  250. HXWeakSelf
  251. self.previewingContext = [self registerForPreviewingWithDelegate:weakSelf sourceView:weakSelf.collectionView];
  252. }
  253. }
  254. }
  255. // }
  256. }
  257. if (!self.manager.configuration.singleSelected && self.manager.configuration.allowSlidingSelection) {
  258. UIPanGestureRecognizer *selectPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(selectPanGestureRecognizerClick:)];
  259. [self.view addGestureRecognizer:selectPanGesture];
  260. }
  261. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationChanged:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
  262. }
  263. #pragma mark - < private >
  264. - (void)setupUI {
  265. [self.view addSubview:self.collectionView];
  266. if ([HXPhotoTools authorizationStatusIsLimited]) {
  267. [self.view addSubview:self.limitView];
  268. }
  269. if (!self.manager.configuration.singleSelected) {
  270. [self.view addSubview:self.bottomView];
  271. }
  272. [self setupNav];
  273. [self changeColor];
  274. }
  275. - (void)setupNav {
  276. UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithTitle:[NSBundle hx_localizedStringForKey:@"取消"] style:UIBarButtonItemStylePlain target:self action:@selector(didCancelClick)];
  277. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  278. if (self.manager.configuration.photoListCancelLocation == HXPhotoListCancelButtonLocationTypeLeft) {
  279. self.navigationItem.leftBarButtonItem = cancelItem;
  280. }else if (self.manager.configuration.photoListCancelLocation == HXPhotoListCancelButtonLocationTypeRight) {
  281. self.navigationItem.rightBarButtonItem = cancelItem;
  282. }
  283. if (self.manager.configuration.photoListTitleView) {
  284. self.navigationItem.titleView = self.manager.configuration.photoListTitleView(self.albumModel.albumName);
  285. HXWeakSelf
  286. self.manager.configuration.photoListTitleViewAction = ^(BOOL selected) {
  287. [weakSelf albumTitleViewDidAction:selected];
  288. };
  289. }else {
  290. self.navigationItem.titleView = self.albumTitleView;
  291. }
  292. [self.view addSubview:self.albumBgView];
  293. [self.view addSubview:self.albumView];
  294. }else {
  295. self.navigationItem.rightBarButtonItem = cancelItem;
  296. }
  297. }
  298. - (void)changeColor {
  299. UIColor *backgroundColor;
  300. UIColor *themeColor;
  301. UIColor *navBarBackgroudColor;
  302. UIColor *albumBgColor;
  303. UIColor *navigationTitleColor;
  304. if ([HXPhotoCommon photoCommon].isDark) {
  305. backgroundColor = [UIColor colorWithRed:0.075 green:0.075 blue:0.075 alpha:1];
  306. themeColor = [UIColor whiteColor];
  307. navBarBackgroudColor = [UIColor blackColor];
  308. albumBgColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
  309. navigationTitleColor = [UIColor whiteColor];
  310. }else {
  311. backgroundColor = self.manager.configuration.photoListViewBgColor;
  312. themeColor = self.manager.configuration.themeColor;
  313. navBarBackgroudColor = self.manager.configuration.navBarBackgroudColor;
  314. navigationTitleColor = self.manager.configuration.navigationTitleColor;
  315. albumBgColor = [UIColor blackColor];
  316. }
  317. self.view.backgroundColor = backgroundColor;
  318. self.collectionView.backgroundColor = backgroundColor;
  319. [self.navigationController.navigationBar setTintColor:themeColor];
  320. self.navigationController.navigationBar.barTintColor = navBarBackgroudColor;
  321. self.navigationController.navigationBar.barStyle = self.manager.configuration.navBarStyle;
  322. if (self.manager.configuration.navBarBackgroundImage) {
  323. [self.navigationController.navigationBar setBackgroundImage:self.manager.configuration.navBarBackgroundImage forBarMetrics:UIBarMetricsDefault];
  324. }
  325. if (self.manager.configuration.navigationTitleSynchColor) {
  326. self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : themeColor};
  327. }else {
  328. if (navigationTitleColor) {
  329. self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : navigationTitleColor};
  330. }else {
  331. self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor blackColor]};
  332. }
  333. }
  334. _albumBgView.backgroundColor = [albumBgColor colorWithAlphaComponent:0.5f];
  335. if (@available(iOS 15.0, *)) {
  336. UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
  337. appearance.titleTextAttributes = self.navigationController.navigationBar.titleTextAttributes;
  338. switch (self.manager.configuration.navBarStyle) {
  339. case UIBarStyleDefault:
  340. appearance.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
  341. break;
  342. default:
  343. appearance.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
  344. break;
  345. }
  346. self.navigationController.navigationBar.standardAppearance = appearance;
  347. self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
  348. }
  349. }
  350. - (void)deviceOrientationChanged:(NSNotification *)notify {
  351. self.beforeOrientationIndexPath = [self.collectionView indexPathsForVisibleItems].firstObject;
  352. self.orientationDidChange = YES;
  353. if (self.navigationController.topViewController != self) {
  354. self.needChangeViewFrame = YES;
  355. }
  356. }
  357. - (CGFloat)getAlbumHeight {
  358. NSInteger count = self.albumView.albumModelArray.count;
  359. if (!count) {
  360. return 0.f;
  361. }
  362. CGFloat cellHeight = self.manager.configuration.popupTableViewCellHeight;
  363. CGFloat albumHeight = cellHeight * count;
  364. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  365. CGFloat albumMaxHeight;
  366. if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown || HX_UI_IS_IPAD) {
  367. albumMaxHeight = self.manager.configuration.popupTableViewHeight;
  368. }else {
  369. albumMaxHeight = self.manager.configuration.popupTableViewHorizontalHeight;
  370. }
  371. if (albumHeight > albumMaxHeight) {
  372. albumHeight = albumMaxHeight;
  373. }
  374. return albumHeight;
  375. }
  376. - (void)changeSubviewFrame {
  377. CGFloat albumHeight = [self getAlbumHeight];
  378. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  379. CGFloat navBarHeight = hxNavigationBarHeight;
  380. NSInteger lineCount = self.manager.configuration.rowCount;
  381. #pragma clang diagnostic push
  382. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  383. if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown || HX_UI_IS_IPAD) {
  384. lineCount = self.manager.configuration.rowCount;
  385. [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
  386. }else if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft){
  387. [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
  388. if ([UIApplication sharedApplication].statusBarHidden) {
  389. navBarHeight = self.navigationController.navigationBar.hx_h;
  390. }else {
  391. navBarHeight = self.navigationController.navigationBar.hx_h + 20;
  392. }
  393. lineCount = self.manager.configuration.horizontalRowCount;
  394. }
  395. #pragma clang diagnostic pop
  396. CGFloat bottomMargin = hxBottomMargin;
  397. CGFloat leftMargin = 0;
  398. CGFloat rightMargin = 0;
  399. CGFloat width = [UIScreen mainScreen].bounds.size.width;
  400. CGFloat height = [UIScreen mainScreen].bounds.size.height;
  401. CGFloat viewWidth = [UIScreen mainScreen].bounds.size.width;
  402. if (!CGRectEqualToRect(self.view.bounds, [UIScreen mainScreen].bounds)) {
  403. self.view.frame = CGRectMake(0, 0, viewWidth, height);
  404. }
  405. if (HX_IS_IPhoneX_All &&
  406. (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)) {
  407. bottomMargin = 21;
  408. leftMargin = 35;
  409. rightMargin = 35;
  410. width = [UIScreen mainScreen].bounds.size.width - 70;
  411. }
  412. CGFloat itemWidth = (width - (lineCount - 1)) / lineCount;
  413. CGFloat itemHeight = itemWidth;
  414. self.flowLayout.itemSize = CGSizeMake(itemWidth, itemHeight);
  415. CGFloat bottomViewY = height - 50 - bottomMargin;
  416. if (!self.manager.configuration.singleSelected) {
  417. self.collectionView.contentInset = UIEdgeInsetsMake(navBarHeight, leftMargin, 50 + bottomMargin, rightMargin);
  418. } else {
  419. self.collectionView.contentInset = UIEdgeInsetsMake(navBarHeight, leftMargin, bottomMargin, rightMargin);
  420. }
  421. #ifdef __IPHONE_13_0
  422. if (@available(iOS 13.0, *)) {
  423. self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 50.f, 0);
  424. }else {
  425. self.collectionView.scrollIndicatorInsets = self.collectionView.contentInset;
  426. }
  427. #else
  428. self.collectionView.scrollIndicatorInsets = self.collectionView.contentInset;
  429. #endif
  430. if (self.orientationDidChange) {
  431. [self.collectionView scrollToItemAtIndexPath:self.beforeOrientationIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
  432. }
  433. self.bottomView.frame = CGRectMake(0, bottomViewY, viewWidth, 50 + bottomMargin);
  434. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  435. self.albumView.hx_w = viewWidth;
  436. self.albumView.hx_h = albumHeight;
  437. BOOL titleViewSeleted = NO;
  438. if (self.manager.configuration.photoListTitleView) {
  439. if (self.manager.configuration.photoListTitleViewSelected) {
  440. titleViewSeleted = self.manager.configuration.photoListTitleViewSelected();
  441. }
  442. if (self.manager.configuration.updatePhotoListTitle) {
  443. self.manager.configuration.updatePhotoListTitle(self.albumModel.albumName);
  444. }
  445. }else {
  446. titleViewSeleted = self.albumTitleView.selected;
  447. self.albumTitleView.model = self.albumModel;
  448. }
  449. if (titleViewSeleted) {
  450. self.albumView.hx_y = navBarHeight;
  451. if (self.manager.configuration.singleSelected) {
  452. self.albumView.alpha = 1;
  453. }
  454. }else {
  455. self.albumView.hx_y = -(navBarHeight + self.albumView.hx_h);
  456. if (self.manager.configuration.singleSelected) {
  457. self.albumView.alpha = 0;
  458. }
  459. }
  460. if (self.manager.configuration.singleSelected) {
  461. self.albumBgView.frame = CGRectMake(0, navBarHeight, viewWidth, height - navBarHeight);
  462. }else {
  463. self.albumBgView.hx_size = CGSizeMake(viewWidth, height);
  464. }
  465. if (self.manager.configuration.popupAlbumTableView) {
  466. self.manager.configuration.popupAlbumTableView(self.albumView.tableView);
  467. }
  468. }
  469. self.navigationController.navigationBar.translucent = self.manager.configuration.navBarTranslucent;
  470. if (!self.manager.configuration.singleSelected) {
  471. if (self.manager.configuration.photoListBottomView) {
  472. self.manager.configuration.photoListBottomView(self.bottomView);
  473. }
  474. }
  475. if (self.manager.configuration.photoListCollectionView) {
  476. self.manager.configuration.photoListCollectionView(self.collectionView);
  477. }
  478. if (self.manager.configuration.navigationBar) {
  479. self.manager.configuration.navigationBar(self.navigationController.navigationBar, self);
  480. }
  481. }
  482. - (void)getCameraRollAlbum {
  483. self.albumModel = self.hx_customNavigationController.cameraRollAlbumModel;
  484. if (self.manager.configuration.updatePhotoListTitle) {
  485. self.manager.configuration.updatePhotoListTitle(self.albumModel.albumName);
  486. }else {
  487. self.albumTitleView.model = self.albumModel;
  488. }
  489. [self getPhotoList];
  490. }
  491. - (void)getAlbumList {
  492. HXWeakSelf
  493. if (self.hx_customNavigationController.cameraRollAlbumModel) {
  494. [self getCameraRollAlbum];
  495. }else {
  496. self.hx_customNavigationController.requestCameraRollCompletion = ^{
  497. [weakSelf getCameraRollAlbum];
  498. };
  499. }
  500. if (self.hx_customNavigationController.albums) {
  501. [self setAlbumModelArray];
  502. }else {
  503. self.hx_customNavigationController.requestAllAlbumCompletion = ^{
  504. [weakSelf setAlbumModelArray];
  505. };
  506. }
  507. }
  508. - (void)setAlbumModelArray {
  509. self.firstDidAlbumTitleView = NO;
  510. self.albumView.albumModelArray = self.hx_customNavigationController.albums;
  511. self.albumView.hx_h = [self getAlbumHeight];
  512. self.albumView.hx_y = -(self.collectionView.contentInset.top + self.albumView.hx_h);
  513. self.albumTitleView.canSelect = YES;
  514. }
  515. - (void)getPhotoList {
  516. [self startGetAllPhotoModel];
  517. }
  518. - (void)didCancelClick {
  519. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  520. if (self.manager.configuration.photoListChangeTitleViewSelected) {
  521. self.manager.configuration.photoListChangeTitleViewSelected(NO);
  522. }
  523. [self.manager cancelBeforeSelectedList];
  524. }
  525. if ([self.delegate respondsToSelector:@selector(photoViewControllerDidCancel:)]) {
  526. [self.delegate photoViewControllerDidCancel:self];
  527. }
  528. if (self.cancelBlock) {
  529. self.cancelBlock(self, self.manager);
  530. }
  531. self.manager.selectPhotoing = NO;
  532. BOOL selectPhotoCancelDismissAnimated = self.manager.selectPhotoCancelDismissAnimated;
  533. [self dismissViewControllerAnimated:selectPhotoCancelDismissAnimated completion:^{
  534. if ([self.delegate respondsToSelector:@selector(photoViewControllerCancelDismissCompletion:)]) {
  535. [self.delegate photoViewControllerCancelDismissCompletion:self];
  536. }
  537. }];
  538. }
  539. - (NSInteger)dateItem:(HXPhotoModel *)model {
  540. NSInteger dateItem = [self.allArray indexOfObject:model];
  541. return dateItem;
  542. }
  543. - (void)scrollToPoint:(HXPhotoViewCell *)cell rect:(CGRect)rect {
  544. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  545. CGFloat navBarHeight = hxNavigationBarHeight;
  546. if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft){
  547. if ([UIApplication sharedApplication].statusBarHidden) {
  548. navBarHeight = self.navigationController.navigationBar.hx_h;
  549. }else {
  550. navBarHeight = self.navigationController.navigationBar.hx_h + 20;
  551. }
  552. }
  553. if (rect.origin.y < navBarHeight) {
  554. [self.collectionView setContentOffset:CGPointMake(0, cell.frame.origin.y - navBarHeight)];
  555. }else if (rect.origin.y + rect.size.height > self.view.hx_h - 50.5 - hxBottomMargin) {
  556. [self.collectionView setContentOffset:CGPointMake(0, cell.frame.origin.y - self.view.hx_h + 50.5 + hxBottomMargin + rect.size.height)];
  557. }
  558. }
  559. - (void)selectPanGestureRecognizerClick:(UIPanGestureRecognizer *)panGesture {
  560. if (self.albumTitleView.selected) {
  561. return;
  562. }
  563. if (panGesture.state == UIGestureRecognizerStateBegan) {
  564. // 获取起始点
  565. self.panSelectStartPoint = [panGesture locationInView:self.collectionView];
  566. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:self.panSelectStartPoint];
  567. // 是否可以选择视频
  568. BOOL canSelectVideo = self.manager.videoSelectedType != HXPhotoManagerVideoSelectedTypeSingle;
  569. if (indexPath) {
  570. // 起始点在cell上
  571. HXPhotoModel *firstModel = self.allArray[indexPath.item];
  572. if (firstModel.subType == HXPhotoModelMediaSubTypeVideo) {
  573. if (canSelectVideo) {
  574. self.currentPanSelectType = !firstModel.selected;
  575. }
  576. }else {
  577. self.currentPanSelectType = !firstModel.selected;
  578. }
  579. }else {
  580. // 起始点不在cell上
  581. self.currentPanSelectType = -1;
  582. }
  583. }else if (panGesture.state == UIGestureRecognizerStateChanged) {
  584. CGPoint currentPoint = [panGesture locationInView:self.collectionView];
  585. NSInteger firstLine = 0;
  586. NSInteger lastLine = 0;
  587. NSIndexPath *firstIndexPath = [self.collectionView indexPathForItemAtPoint:self.panSelectStartPoint];
  588. if (!firstIndexPath) {
  589. // 起始点不在cell上直接不可滑动选择
  590. return;
  591. }
  592. NSIndexPath *lastIndexPath = [self.collectionView indexPathForItemAtPoint:currentPoint];
  593. if (!lastIndexPath) {
  594. return;
  595. }
  596. NSInteger rowCount = self.manager.configuration.rowCount;
  597. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  598. if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft){
  599. rowCount = self.manager.configuration.horizontalRowCount;
  600. }
  601. if ((firstIndexPath.item + 1) % rowCount == 0) {
  602. firstLine = (firstIndexPath.item + 1) / rowCount;
  603. }else {
  604. firstLine = (firstIndexPath.item + 1) / rowCount + 1;
  605. }
  606. if ((lastIndexPath.item + 1) % rowCount == 0) {
  607. lastLine = (lastIndexPath.item + 1) / rowCount;
  608. }else {
  609. lastLine = (lastIndexPath.item + 1) / rowCount + 1;
  610. }
  611. NSMutableArray *indexPaths = [NSMutableArray array];
  612. CGFloat startX;
  613. CGFloat maxX;
  614. BOOL xReverse = NO;
  615. if (currentPoint.x > self.panSelectStartPoint.x) {
  616. // 向右
  617. maxX = [self panSelectGetMaxXWithPoint:currentPoint];
  618. startX = [self panSelectGetMinXWithPoint:self.panSelectStartPoint];
  619. }else {
  620. // 向左
  621. xReverse = YES;
  622. maxX = [self panSelectGetMaxXWithPoint:self.panSelectStartPoint];
  623. startX = [self panSelectGetMinXWithPoint:currentPoint];
  624. }
  625. CGFloat maxY;
  626. CGFloat startY;
  627. BOOL yReverse = NO;
  628. if (currentPoint.y > self.panSelectStartPoint.y) {
  629. // 向下
  630. maxY = [self panSelectGetMaxYWithPoint:currentPoint];
  631. startY = [self panSelectGetMinYWithPoint:self.panSelectStartPoint];
  632. }else {
  633. // 向上
  634. yReverse = YES;
  635. maxY = [self panSelectGetMaxYWithPoint:self.panSelectStartPoint];
  636. startY = [self panSelectGetMinYWithPoint:currentPoint];
  637. }
  638. NSInteger distanceW = self.flowLayout.minimumInteritemSpacing + self.flowLayout.itemSize.width;
  639. NSInteger distanceH = self.flowLayout.minimumInteritemSpacing + self.flowLayout.itemSize.height;
  640. BOOL canSelectVideo = self.manager.videoSelectedType != HXPhotoManagerVideoSelectedTypeSingle;
  641. NSIndexPath *sIndexPath = [self.collectionView indexPathForItemAtPoint:self.panSelectStartPoint];
  642. if (sIndexPath && ![indexPaths containsObject:sIndexPath]) {
  643. HXPhotoModel *model = self.allArray[sIndexPath.item];
  644. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  645. if (canSelectVideo) {
  646. [indexPaths addObject:sIndexPath];
  647. }
  648. }else {
  649. [indexPaths addObject:sIndexPath];
  650. }
  651. }
  652. while (yReverse ? maxY > startY : startY < maxY) {
  653. CGFloat tempStartX = startX;
  654. CGFloat tempMaxX = maxX;
  655. NSInteger currentLine = 0;
  656. NSIndexPath *currentIndexPath;
  657. if (yReverse) {
  658. currentIndexPath = [self.collectionView indexPathForItemAtPoint:CGPointMake(tempMaxX - 1, maxY - 1)];
  659. }else {
  660. currentIndexPath = [self.collectionView indexPathForItemAtPoint:CGPointMake(tempStartX + 1, startY + 1)];
  661. }
  662. if ((currentIndexPath.item + 1) % rowCount == 0) {
  663. currentLine = (currentIndexPath.item + 1) / rowCount;
  664. }else {
  665. currentLine = (currentIndexPath.item + 1) / rowCount + 1;
  666. }
  667. if (currentLine == firstLine) {
  668. if (lastLine != firstLine) {
  669. if (yReverse) {
  670. tempMaxX = [self panSelectGetMaxXWithPoint:self.panSelectStartPoint];
  671. tempStartX = 2;
  672. }else {
  673. if (xReverse) {
  674. tempStartX = [self panSelectGetMinXWithPoint:self.panSelectStartPoint];
  675. }
  676. tempMaxX = HX_ScreenWidth - 2;
  677. }
  678. }
  679. }else if (currentLine == lastLine) {
  680. if (yReverse) {
  681. tempStartX = [self panSelectGetMinXWithPoint:currentPoint];
  682. tempMaxX = HX_ScreenWidth - 2;
  683. }else {
  684. tempStartX = 2;
  685. if (xReverse) {
  686. tempMaxX = [self panSelectGetMaxXWithPoint:currentPoint];
  687. }
  688. }
  689. }else if (currentLine != firstLine && currentLine != lastLine) {
  690. tempStartX = 2;
  691. tempMaxX = HX_ScreenWidth - 2;
  692. }
  693. while (yReverse ? tempMaxX > tempStartX : tempStartX < tempMaxX) {
  694. NSIndexPath *indexPath;
  695. if (yReverse) {
  696. indexPath = [self panSelectCurrentIndexPathWithPoint:CGPointMake(tempMaxX, maxY) indexPaths:indexPaths canSelectVideo:canSelectVideo];
  697. }else {
  698. indexPath = [self panSelectCurrentIndexPathWithPoint:CGPointMake(tempStartX, startY) indexPaths:indexPaths canSelectVideo:canSelectVideo];
  699. }
  700. if (indexPath) {
  701. [indexPaths addObject:indexPath];
  702. }
  703. if (yReverse) {
  704. tempMaxX -= distanceW / 2;
  705. }else {
  706. tempStartX += distanceW / 2;
  707. }
  708. }
  709. if (yReverse) {
  710. maxY -= distanceH / 2;
  711. }else {
  712. startY += distanceH / 2;
  713. }
  714. }
  715. NSIndexPath *eIndexPath = [self.collectionView indexPathForItemAtPoint:currentPoint];
  716. if (eIndexPath && ![indexPaths containsObject:eIndexPath]) {
  717. HXPhotoModel *model = self.allArray[eIndexPath.item];
  718. if (self.currentPanSelectType == 0) {
  719. if (model.selected) {
  720. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  721. if (canSelectVideo) {
  722. [indexPaths addObject:eIndexPath];
  723. }
  724. }else {
  725. [indexPaths addObject:eIndexPath];
  726. }
  727. }
  728. }else if (self.currentPanSelectType == 1) {
  729. if (!model.selected) {
  730. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  731. if (canSelectVideo) {
  732. [indexPaths addObject:eIndexPath];
  733. }
  734. }else {
  735. [indexPaths addObject:eIndexPath];
  736. }
  737. }
  738. }
  739. }
  740. if (self.currentPanSelectType == -1) {
  741. NSIndexPath *firstIndexPath = indexPaths.firstObject;
  742. HXPhotoModel *firstModel;
  743. if (firstIndexPath) {
  744. firstModel = self.allArray[firstIndexPath.item];
  745. self.currentPanSelectType = !firstModel.selected;
  746. }
  747. }
  748. NSMutableArray *reloadSelectArray = [NSMutableArray array];
  749. for (NSIndexPath *indexPath in indexPaths) {
  750. HXPhotoModel *model = self.allArray[indexPath.item];
  751. if (model.type == HXPhotoModelMediaTypeCamera ||
  752. model.type == HXPhotoModelMediaTypeLimit) {
  753. continue;
  754. }
  755. if (model.subType == HXPhotoModelMediaSubTypeVideo && !canSelectVideo) {
  756. continue;
  757. }
  758. if (self.currentPanSelectType == 0) {
  759. // 取消选择
  760. if (model.selected) {
  761. [self.manager beforeSelectedListdeletePhotoModel:model];
  762. if (![reloadSelectArray containsObject:indexPath]) {
  763. [reloadSelectArray addObject:indexPath];
  764. }
  765. }
  766. }else if (self.currentPanSelectType == 1) {
  767. // 选择
  768. if (!model.selected) {
  769. if (model.isICloud) {
  770. // 是iCloud上的资源就过滤掉
  771. continue;
  772. }
  773. // 是否可以选择
  774. NSString *str = [self.manager maximumOfJudgment:model];
  775. if (!str) {
  776. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  777. model.thumbPhoto = cell.imageView.image;
  778. [self.manager beforeSelectedListAddPhotoModel:model];
  779. if (![reloadSelectArray containsObject:indexPath]) {
  780. [reloadSelectArray addObject:indexPath];
  781. }
  782. }else {
  783. if (self.imagePromptView && [self.imagePromptView.text isEqualToString:str]) {
  784. continue;
  785. }
  786. [self showImagePromptViewWithText:str];
  787. }
  788. }else {
  789. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  790. if (![cell.selectBtn.currentTitle isEqualToString:model.selectIndexStr] || !cell.selectBtn.selected) {
  791. if (![reloadSelectArray containsObject:indexPath]) {
  792. [reloadSelectArray addObject:indexPath];
  793. }
  794. }
  795. }
  796. }
  797. }
  798. NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",indexPaths];
  799. NSArray * filterArray = [self.panSelectIndexPaths filteredArrayUsingPredicate:filterPredicate];
  800. for (NSIndexPath *indexPath in filterArray) {
  801. HXPhotoModel *model = self.allArray[indexPath.item];
  802. if (model.type == HXPhotoModelMediaTypeCamera ||
  803. model.type == HXPhotoModelMediaTypeLimit) {
  804. continue;
  805. }
  806. if (model.subType == HXPhotoModelMediaSubTypeVideo && !canSelectVideo) {
  807. continue;
  808. }
  809. if (self.currentPanSelectType == 0) {
  810. if (!model.selected) {
  811. [self.manager beforeSelectedListAddPhotoModel:model];
  812. if (![reloadSelectArray containsObject:indexPath]) {
  813. [reloadSelectArray addObject:indexPath];
  814. }
  815. }
  816. }else if (self.currentPanSelectType == 1) {
  817. if (model.selected) {
  818. [self.manager beforeSelectedListdeletePhotoModel:model];
  819. if (![reloadSelectArray containsObject:indexPath]) {
  820. [reloadSelectArray addObject:indexPath];
  821. }
  822. }
  823. }
  824. }
  825. if (self.currentPanSelectType == 0) {
  826. for (HXPhotoModel *model in [self.manager selectedArray]) {
  827. if (model.currentAlbumIndex != self.albumModel.index) {
  828. continue;
  829. }
  830. if (!model.dateCellIsVisible) {
  831. continue;
  832. }
  833. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:model] inSection:0];
  834. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  835. if (cell && ![cell.selectBtn.currentTitle isEqualToString:model.selectIndexStr]) {
  836. if (![reloadSelectArray containsObject:indexPath]) {
  837. [reloadSelectArray addObject:indexPath];
  838. }
  839. }
  840. }
  841. }
  842. [reloadSelectArray addObjectsFromArray:[self getVisibleVideoCellIndexPathsWithCurrentIndexPaths:reloadSelectArray]];
  843. if (reloadSelectArray.count) {
  844. [self.collectionView reloadItemsAtIndexPaths:reloadSelectArray];
  845. self.bottomView.selectCount = [self.manager selectedCount];
  846. }
  847. self.panSelectIndexPaths = indexPaths;
  848. }else if (panGesture.state == UIGestureRecognizerStateEnded ||
  849. panGesture.state == UIGestureRecognizerStateCancelled) {
  850. self.panSelectIndexPaths = nil;
  851. self.currentPanSelectType = -1;
  852. }
  853. }
  854. - (CGFloat)panSelectGetMinYWithPoint:(CGPoint)point {
  855. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  856. UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
  857. return cell.hx_y + 2;
  858. }
  859. - (CGFloat)panSelectGetMaxYWithPoint:(CGPoint)point {
  860. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  861. UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
  862. return CGRectGetMaxY(cell.frame) - 2;
  863. }
  864. - (CGFloat)panSelectGetMinXWithPoint:(CGPoint)point {
  865. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  866. UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
  867. return cell.hx_x + 2;
  868. }
  869. - (CGFloat)panSelectGetMaxXWithPoint:(CGPoint)point {
  870. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  871. UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
  872. return CGRectGetMaxX(cell.frame) - 2;
  873. }
  874. - (NSIndexPath *)panSelectCurrentIndexPathWithPoint:(CGPoint)point indexPaths:(NSMutableArray *)indexPaths canSelectVideo:(BOOL)canSelectVideo {
  875. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
  876. if (indexPath && ![indexPaths containsObject:indexPath]) {
  877. HXPhotoModel *model = self.allArray[indexPath.item];
  878. if (self.currentPanSelectType == 0) {
  879. if (!model.selected && ![self.panSelectIndexPaths containsObject:indexPath]) {
  880. return nil;
  881. }
  882. }else if (self.currentPanSelectType == 1) {
  883. if (model.selected && ![self.panSelectIndexPaths containsObject:indexPath]) {
  884. return nil;
  885. }
  886. }
  887. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  888. if (canSelectVideo) {
  889. return indexPath;
  890. }
  891. }else {
  892. return indexPath;
  893. }
  894. }
  895. return nil;
  896. }
  897. - (NSMutableArray *)getVisibleVideoCellIndexPathsWithCurrentIndexPaths:(NSMutableArray *)currentIndexPath {
  898. NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.collectionView.visibleCells.count];
  899. for (UICollectionViewCell *tempCell in self.collectionView.visibleCells) {
  900. if ([tempCell isKindOfClass:[HXPhotoViewCell class]]) {
  901. HXPhotoViewCell *cell = (HXPhotoViewCell *)tempCell;
  902. BOOL canSelect = NO;
  903. if (!cell.model.selected) {
  904. if (cell.model.subType == HXPhotoModelMediaSubTypePhoto) {
  905. canSelect = self.manager.beforeCanSelectPhoto;
  906. }else if (cell.model.subType == HXPhotoModelMediaSubTypeVideo) {
  907. canSelect = [self.manager beforeCanSelectVideoWithModel:cell.model];
  908. }
  909. }else {
  910. canSelect = YES;
  911. }
  912. if ((cell.videoMaskLayer.hidden && !canSelect) || (!cell.videoMaskLayer.hidden && canSelect)) {
  913. NSIndexPath *indexPath = [self.collectionView indexPathForCell:tempCell];
  914. if (![currentIndexPath containsObject:indexPath]) {
  915. [array addObject:indexPath];
  916. }
  917. }
  918. }
  919. }
  920. return array;
  921. }
  922. - (void)showImagePromptViewWithText:(NSString *)text {
  923. [UIView cancelPreviousPerformRequestsWithTarget:self];
  924. [self.imagePromptView removeFromSuperview];
  925. CGFloat hudW = [UILabel hx_getTextWidthWithText:text height:15 fontSize:14];
  926. if (hudW > self.view.hx_w - 60) {
  927. hudW = self.view.hx_w - 60;
  928. }
  929. CGFloat hudH = [UILabel hx_getTextHeightWithText:text width:hudW fontSize:14];
  930. if (hudW < 100) {
  931. hudW = 100;
  932. }
  933. self.imagePromptView = [[HXHUD alloc] initWithFrame:CGRectMake(0, 0, hudW + 20, 110 + hudH - 15) imageName:@"hx_alert_failed" text:text];
  934. self.imagePromptView.alpha = 0;
  935. [self.view addSubview:self.imagePromptView];
  936. self.imagePromptView.center = CGPointMake(self.view.hx_w / 2, self.view.hx_h / 2);
  937. self.imagePromptView.transform = CGAffineTransformMakeScale(0.4, 0.4);
  938. [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{
  939. self.imagePromptView.alpha = 1;
  940. self.imagePromptView.transform = CGAffineTransformIdentity;
  941. } completion:nil];
  942. [self performSelector:@selector(hideImagePromptView) withObject:nil afterDelay:1.75f inModes:@[NSRunLoopCommonModes]];
  943. }
  944. - (void)hideImagePromptView {
  945. [UIView animateWithDuration:0.25f animations:^{
  946. self.imagePromptView.alpha = 0;
  947. self.imagePromptView.transform = CGAffineTransformMakeScale(0.5, 0.5);
  948. } completion:^(BOOL finished) {
  949. [self.imagePromptView removeFromSuperview];
  950. self.imagePromptView = nil;
  951. }];
  952. }
  953. #pragma mark - < public >
  954. - (void)startGetAllPhotoModel {
  955. HXWeakSelf
  956. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  957. [self.manager getPhotoListWithAlbumModel:self.albumModel
  958. complete:^(NSMutableArray * _Nullable allList, NSMutableArray * _Nullable previewList, NSUInteger photoCount, NSUInteger videoCount, HXPhotoModel * _Nullable firstSelectModel, HXAlbumModel * _Nullable albumModel) {
  959. if ((weakSelf.albumModel != albumModel && !weakSelf.assetDidChanged) ||
  960. !weakSelf) {
  961. return;
  962. }
  963. weakSelf.assetDidChanged = NO;
  964. if (weakSelf.collectionViewReloadCompletion) {
  965. return ;
  966. }
  967. weakSelf.photoCount = photoCount + weakSelf.manager.cameraPhotoCount;
  968. weakSelf.videoCount = videoCount + weakSelf.manager.cameraVideoCount;
  969. [weakSelf setPhotoModelsWithAllList:allList previewList:previewList firstSelectModel:firstSelectModel];
  970. }];
  971. });
  972. }
  973. - (void)setPhotoModelsWithAllList:(NSMutableArray *)allList
  974. previewList:(NSMutableArray *)previewList
  975. firstSelectModel:(HXPhotoModel *)firstSelectModel {
  976. self.collectionViewReloadCompletion = YES;
  977. self.allArray = allList.mutableCopy;
  978. if (self.allArray.count && self.showBottomPhotoCount) {
  979. if (!self.photoCount && !self.videoCount) {
  980. self.manager.configuration.showBottomPhotoDetail = NO;
  981. }else {
  982. self.manager.configuration.showBottomPhotoDetail = YES;
  983. }
  984. }
  985. self.previewArray = previewList.mutableCopy;
  986. [self reloadCollectionViewWithFirstSelectModel:firstSelectModel];
  987. }
  988. - (void)reloadCollectionViewWithFirstSelectModel:(HXPhotoModel *)firstSelectModel {
  989. dispatch_async(dispatch_get_main_queue(), ^{
  990. if (!self.firstOn) {
  991. self.cellCanSetModel = NO;
  992. [self.hx_customNavigationController.view hx_handleLoading];
  993. }else {
  994. [self.hx_customNavigationController.view hx_handleLoading:NO];
  995. }
  996. [self.collectionView reloadData];
  997. [self collectionViewReloadFinishedWithFirstSelectModel:firstSelectModel];
  998. if (!self.firstOn) {
  999. dispatch_async(dispatch_get_main_queue(),^{
  1000. // 在 collectionView reload完成之后一个一个的cell去获取image,防止一次性获取造成卡顿
  1001. self.collectionVisibleCells = [self.collectionView.visibleCells sortedArrayUsingComparator:^NSComparisonResult(HXPhotoViewCell *obj1, HXPhotoViewCell *obj2) {
  1002. // visibleCells 这个数组的数据顺序是乱的,所以在获取image之前先将可见cell排序
  1003. NSIndexPath *indexPath1 = [self.collectionView indexPathForCell:obj1];
  1004. NSIndexPath *indexPath2 = [self.collectionView indexPathForCell:obj2];
  1005. if (indexPath1.item > indexPath2.item) {
  1006. return NSOrderedDescending;
  1007. }else {
  1008. return NSOrderedAscending;
  1009. }
  1010. }];
  1011. // 排序完成之后从上到下依次获取image
  1012. [self cellSetModelData:self.collectionVisibleCells.firstObject];
  1013. });
  1014. }
  1015. });
  1016. }
  1017. - (void)cellSetModelData:(HXPhotoViewCell *)cell {
  1018. if ([cell isKindOfClass:[HXPhotoViewCell class]]) {
  1019. HXWeakSelf
  1020. cell.alpha = 0;
  1021. [cell setModelDataWithHighQuality:YES completion:^(HXPhotoViewCell *myCell) {
  1022. [UIView animateWithDuration:0.125 animations:^{
  1023. myCell.alpha = 1;
  1024. }];
  1025. NSInteger count = weakSelf.collectionVisibleCells.count;
  1026. NSInteger index = [weakSelf.collectionVisibleCells indexOfObject:myCell];
  1027. if (index < count - 1) {
  1028. [weakSelf cellSetModelData:weakSelf.collectionVisibleCells[index + 1]];
  1029. }else {
  1030. // 可见cell已全部设置
  1031. weakSelf.cellCanSetModel = YES;
  1032. weakSelf.collectionVisibleCells = nil;
  1033. }
  1034. }];
  1035. }else {
  1036. cell.hidden = NO;
  1037. NSInteger count = self.collectionVisibleCells.count;
  1038. NSInteger index = [self.collectionVisibleCells indexOfObject:cell];
  1039. if (index < count - 1) {
  1040. [self cellSetModelData:self.collectionVisibleCells[index + 1]];
  1041. }else {
  1042. self.cellCanSetModel = YES;
  1043. self.collectionVisibleCells = nil;
  1044. }
  1045. }
  1046. }
  1047. - (void)collectionViewReloadFinishedWithFirstSelectModel:(HXPhotoModel *)firstSelectModel {
  1048. if (self.allArray.count == 0) {
  1049. return;
  1050. }
  1051. if (!self.manager.configuration.singleSelected) {
  1052. self.bottomView.selectCount = self.manager.selectedArray.count;
  1053. }
  1054. NSIndexPath *scrollIndexPath;
  1055. UICollectionViewScrollPosition position = UICollectionViewScrollPositionNone;
  1056. if (!self.manager.configuration.reverseDate) {
  1057. if (self.allArray.count > 0) {
  1058. if (firstSelectModel) {
  1059. scrollIndexPath = [NSIndexPath indexPathForItem:[self.allArray indexOfObject:firstSelectModel] inSection:0];
  1060. position = UICollectionViewScrollPositionCenteredVertically;
  1061. }else {
  1062. NSInteger forItem = (self.allArray.count - 1) <= 0 ? 0 : self.allArray.count - 1;
  1063. scrollIndexPath = [NSIndexPath indexPathForItem:forItem inSection:0];
  1064. position = UICollectionViewScrollPositionBottom;
  1065. }
  1066. }
  1067. }else {
  1068. if (firstSelectModel) {
  1069. scrollIndexPath = [NSIndexPath indexPathForItem:[self.allArray indexOfObject:firstSelectModel] inSection:0];
  1070. position = UICollectionViewScrollPositionCenteredVertically;
  1071. }else {
  1072. scrollIndexPath = [NSIndexPath indexPathForItem:0 inSection:0];
  1073. position = UICollectionViewScrollPositionTop;
  1074. }
  1075. }
  1076. if (scrollIndexPath) {
  1077. [self.collectionView scrollToItemAtIndexPath:scrollIndexPath atScrollPosition:position animated:NO];
  1078. }
  1079. }
  1080. - (HXPhotoViewCell *)currentPreviewCell:(HXPhotoModel *)model {
  1081. if (!model || ![self.allArray containsObject:model]) {
  1082. return nil;
  1083. }
  1084. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:model] inSection:0];
  1085. return (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1086. }
  1087. - (BOOL)scrollToModel:(HXPhotoModel *)model {
  1088. BOOL isContainsModel = [self.allArray containsObject:model];
  1089. if (isContainsModel) {
  1090. [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:[self dateItem:model] inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
  1091. [self.collectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:[self dateItem:model] inSection:0]]];
  1092. }
  1093. return isContainsModel;
  1094. }
  1095. #pragma mark - < HXCustomCameraViewControllerDelegate >
  1096. - (void)customCameraViewController:(HXCustomCameraViewController *)viewController didDone:(HXPhotoModel *)model {
  1097. model.currentAlbumIndex = self.albumModel.index;
  1098. if (!self.manager.configuration.singleSelected) {
  1099. [self.manager beforeListAddCameraTakePicturesModel:model];
  1100. }
  1101. if ([HXPhotoTools authorizationStatusIsLimited]) {
  1102. return;
  1103. }
  1104. if (model.asset) {
  1105. [self.manager addTempCameraAssetModel:model];
  1106. }
  1107. if (model.type != HXPhotoModelMediaTypeCameraPhoto &&
  1108. model.type != HXPhotoModelMediaTypeCameraVideo) {
  1109. HXAlbumModel *albumModel = self.albumView.albumModelArray.firstObject;
  1110. if (albumModel.count == 0) {
  1111. albumModel.assetResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[model.localIdentifier] options:nil];
  1112. }
  1113. albumModel.count++;
  1114. }
  1115. if (model.subType == HXPhotoModelMediaSubTypePhoto) {
  1116. self.photoCount++;
  1117. }else if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  1118. self.videoCount++;
  1119. }
  1120. if (self.albumModel.realCount != self.photoCount + self.videoCount) {
  1121. self.albumModel.realCount = self.photoCount + self.videoCount;
  1122. }
  1123. [self collectionViewAddModel:model beforeModel:nil];
  1124. if ([self.delegate respondsToSelector:@selector(photoViewControllerDidChangeSelect:selected:)]) {
  1125. [self.delegate photoViewControllerDidChangeSelect:model selected:model.selected];
  1126. }
  1127. }
  1128. - (void)collectionViewAddModel:(HXPhotoModel *)model beforeModel:(HXPhotoModel *)beforeModel {
  1129. NSInteger cameraIndex = self.manager.configuration.openCamera ? 1 : 0;
  1130. if (beforeModel) {
  1131. NSInteger allIndex = cameraIndex;
  1132. NSInteger previewIndex = 0;
  1133. if ([self.allArray containsObject:beforeModel]) {
  1134. allIndex = [self.allArray indexOfObject:beforeModel];
  1135. }
  1136. if ([self.previewArray containsObject:beforeModel]) {
  1137. previewIndex = [self.previewArray indexOfObject:beforeModel];
  1138. }
  1139. [self.allArray insertObject:model atIndex:allIndex];
  1140. [self.previewArray insertObject:model atIndex:previewIndex];
  1141. }else {
  1142. if (self.manager.configuration.reverseDate) {
  1143. [self.allArray insertObject:model atIndex:cameraIndex];
  1144. [self.previewArray insertObject:model atIndex:0];
  1145. }else {
  1146. NSInteger count = self.allArray.count - cameraIndex;
  1147. [self.allArray insertObject:model atIndex:count];
  1148. [self.previewArray addObject:model];
  1149. }
  1150. }
  1151. if (beforeModel && [self.allArray containsObject:model]) {
  1152. NSInteger index = [self.allArray indexOfObject:model];
  1153. [self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
  1154. }else {
  1155. if (self.manager.configuration.reverseDate) {
  1156. [self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:cameraIndex inSection:0]]];
  1157. }else {
  1158. NSInteger count = self.allArray.count - 1;
  1159. [self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:count - cameraIndex inSection:0]]];
  1160. }
  1161. }
  1162. self.footerView.photoCount = self.photoCount;
  1163. self.footerView.videoCount = self.videoCount;
  1164. self.bottomView.selectCount = [self.manager selectedCount];
  1165. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  1166. [self.albumView refreshCamearCount];
  1167. }else if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModeDefault) {
  1168. [[NSNotificationCenter defaultCenter] postNotificationName:@"CustomCameraViewControllerDidDoneNotification" object:nil];
  1169. }
  1170. }
  1171. #pragma mark - < UICollectionViewDataSource >
  1172. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  1173. return 1;
  1174. }
  1175. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  1176. return self.allArray.count;
  1177. }
  1178. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  1179. HXPhotoModel *model;
  1180. if (indexPath.item < self.allArray.count) {
  1181. model = self.allArray[indexPath.item];
  1182. }
  1183. model.dateCellIsVisible = YES;
  1184. if (model.type == HXPhotoModelMediaTypeCamera) {
  1185. HXPhotoCameraViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HXPhotoCameraViewCellId" forIndexPath:indexPath];
  1186. cell.bgColor = self.manager.configuration.photoListTakePhotoBgColor;
  1187. cell.model = model;
  1188. if (!self.cameraCell) {
  1189. cell.cameraImage = [HXPhotoCommon photoCommon].cameraImage;
  1190. self.cameraCell = cell;
  1191. }
  1192. if (!self.cellCanSetModel) {
  1193. cell.hidden = YES;
  1194. }
  1195. return cell;
  1196. }else if (model.type == HXPhotoModelMediaTypeLimit) {
  1197. HXPhotoLimitViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HXPhotoLimitViewCellId" forIndexPath:indexPath];
  1198. cell.lineColor = self.manager.configuration.photoListLimitCellLineColor;
  1199. cell.lineDarkColor = self.manager.configuration.photoListLimitCellLineDarkColor;
  1200. cell.textColor = self.manager.configuration.photoListLimitCellTextColor;
  1201. cell.textDarkColor = self.manager.configuration.photoListLimitCellTextDarkColor;
  1202. cell.textFont = self.manager.configuration.photoListLimitCellTextFont;
  1203. cell.bgColor = self.manager.configuration.photoListLimitCellBackgroundColor;
  1204. cell.bgDarkColor = self.manager.configuration.photoListLimitCellBackgroundDarkColor;
  1205. [cell config];
  1206. return cell;
  1207. }else {
  1208. HXPhotoViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HXPhotoViewCellID" forIndexPath:indexPath];
  1209. cell.delegate = self;
  1210. cell.darkSelectBgColor = self.manager.configuration.cellDarkSelectBgColor;
  1211. cell.darkSelectedTitleColor = self.manager.configuration.cellDarkSelectTitleColor;
  1212. if (!model.selected) {
  1213. if (model.subType == HXPhotoModelMediaSubTypePhoto) {
  1214. cell.canSelect = self.manager.beforeCanSelectPhoto;
  1215. }else if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  1216. cell.canSelect = [self.manager beforeCanSelectVideoWithModel:model];
  1217. }
  1218. }else {
  1219. cell.canSelect = YES;
  1220. }
  1221. UIColor *cellSelectedTitleColor = self.manager.configuration.cellSelectedTitleColor;
  1222. UIColor *selectedTitleColor = self.manager.configuration.selectedTitleColor;
  1223. UIColor *cellSelectedBgColor = self.manager.configuration.cellSelectedBgColor;
  1224. if (cellSelectedTitleColor) {
  1225. cell.selectedTitleColor = cellSelectedTitleColor;
  1226. }else if (selectedTitleColor) {
  1227. cell.selectedTitleColor = selectedTitleColor;
  1228. }
  1229. if (cellSelectedBgColor) {
  1230. cell.selectBgColor = cellSelectedBgColor;
  1231. }else {
  1232. cell.selectBgColor = self.manager.configuration.themeColor;
  1233. }
  1234. if (self.cellCanSetModel) {
  1235. [cell setModel:model emptyImage:NO];
  1236. [cell setModelDataWithHighQuality:NO completion:nil];
  1237. }else {
  1238. [cell setModel:model emptyImage:YES];
  1239. }
  1240. cell.singleSelected = self.manager.configuration.singleSelected;
  1241. return cell;
  1242. }
  1243. }
  1244. #pragma mark - < UICollectionViewDelegate >
  1245. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  1246. if (self.navigationController.topViewController != self) {
  1247. return;
  1248. }
  1249. HXPhotoModel *model = self.allArray[indexPath.item];
  1250. if (model.type == HXPhotoModelMediaTypeCamera) {
  1251. if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  1252. [self.view hx_showImageHUDText:[NSBundle hx_localizedStringForKey:@"无法使用相机!"]];
  1253. return;
  1254. }
  1255. HXWeakSelf
  1256. [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
  1257. dispatch_async(dispatch_get_main_queue(), ^{
  1258. if (granted) {
  1259. if (weakSelf.manager.configuration.replaceCameraViewController) {
  1260. HXPhotoConfigurationCameraType cameraType;
  1261. if (weakSelf.manager.type == HXPhotoManagerSelectedTypePhoto) {
  1262. cameraType = HXPhotoConfigurationCameraTypePhoto;
  1263. }else if (weakSelf.manager.type == HXPhotoManagerSelectedTypeVideo) {
  1264. cameraType = HXPhotoConfigurationCameraTypeVideo;
  1265. }else {
  1266. if (!weakSelf.manager.configuration.selectTogether) {
  1267. if (weakSelf.manager.selectedPhotoArray.count > 0) {
  1268. cameraType = HXPhotoConfigurationCameraTypePhoto;
  1269. }else if (weakSelf.manager.selectedVideoArray.count > 0) {
  1270. cameraType = HXPhotoConfigurationCameraTypeVideo;
  1271. }else {
  1272. cameraType = HXPhotoConfigurationCameraTypePhotoAndVideo;
  1273. }
  1274. }else {
  1275. cameraType = HXPhotoConfigurationCameraTypePhotoAndVideo;
  1276. }
  1277. }
  1278. switch (weakSelf.manager.configuration.customCameraType) {
  1279. case HXPhotoCustomCameraTypePhoto:
  1280. cameraType = HXPhotoConfigurationCameraTypePhoto;
  1281. break;
  1282. case HXPhotoCustomCameraTypeVideo:
  1283. cameraType = HXPhotoConfigurationCameraTypeVideo;
  1284. break;
  1285. case HXPhotoCustomCameraTypePhotoAndVideo:
  1286. cameraType = HXPhotoConfigurationCameraTypePhotoAndVideo;
  1287. break;
  1288. default:
  1289. break;
  1290. }
  1291. if (weakSelf.manager.configuration.shouldUseCamera) {
  1292. weakSelf.manager.configuration.shouldUseCamera(weakSelf, cameraType, weakSelf.manager);
  1293. }
  1294. weakSelf.manager.configuration.useCameraComplete = ^(HXPhotoModel *model) {
  1295. if (round(model.videoDuration) < weakSelf.manager.configuration.videoMinimumSelectDuration) {
  1296. [weakSelf.view hx_showImageHUDText:[NSString stringWithFormat:[NSBundle hx_localizedStringForKey:@"视频少于%ld秒,无法选择"], weakSelf.manager.configuration.videoMinimumSelectDuration]];
  1297. }else if (round(model.videoDuration) >= weakSelf.manager.configuration.videoMaximumSelectDuration + 1) {
  1298. [weakSelf.view hx_showImageHUDText:[NSString stringWithFormat:[NSBundle hx_localizedStringForKey:@"视频大于%ld秒,无法选择"], weakSelf.manager.configuration.videoMaximumSelectDuration]];
  1299. }
  1300. [weakSelf customCameraViewController:nil didDone:model];
  1301. };
  1302. return;
  1303. }
  1304. HXCustomCameraViewController *vc = [[HXCustomCameraViewController alloc] init];
  1305. vc.delegate = weakSelf;
  1306. vc.manager = weakSelf.manager;
  1307. HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:vc];
  1308. nav.isCamera = YES;
  1309. nav.supportRotation = weakSelf.manager.configuration.supportRotation;
  1310. nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1311. nav.modalPresentationCapturesStatusBarAppearance = YES;
  1312. [weakSelf presentViewController:nav animated:YES completion:nil];
  1313. }else {
  1314. [HXPhotoTools showUnusableCameraAlert:weakSelf];
  1315. }
  1316. });
  1317. }];
  1318. }else if (model.type == HXPhotoModelMediaTypeLimit) {
  1319. if (@available(iOS 14, *)) {
  1320. [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
  1321. }
  1322. }else {
  1323. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1324. if (cell.model.isICloud) {
  1325. if (!cell.model.iCloudDownloading) {
  1326. [cell startRequestICloudAsset];
  1327. }
  1328. return;
  1329. }
  1330. if (!cell.canSelect) {
  1331. [self.view hx_showImageHUDText:[self.manager maximumOfJudgment:cell.model]];
  1332. return;
  1333. }
  1334. if (cell.model.subType == HXPhotoModelMediaSubTypeVideo) {
  1335. if (cell.model.videoDuration >= self.manager.configuration.videoMaximumSelectDuration + 1) {
  1336. if (self.manager.configuration.selectVideoBeyondTheLimitTimeAutoEdit &&
  1337. self.manager.configuration.videoCanEdit) {
  1338. if (cell.model.cameraVideoType == HXPhotoModelMediaTypeCameraVideoTypeNetWork) {
  1339. if (self.manager.configuration.selectNetworkVideoCanEdit) {
  1340. [self jumpVideoEditWithModel:cell.model];
  1341. return;
  1342. }
  1343. }else {
  1344. [self jumpVideoEditWithModel:cell.model];
  1345. return;
  1346. }
  1347. }
  1348. }
  1349. }
  1350. if (!self.manager.configuration.singleSelected) {
  1351. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1352. if (HX_IOS9Earlier) {
  1353. previewVC.photoViewController = self;
  1354. }
  1355. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1356. previewVC.delegate = self;
  1357. previewVC.modelArray = self.previewArray;
  1358. previewVC.manager = self.manager;
  1359. previewVC.currentModelIndex = currentIndex;
  1360. self.navigationController.delegate = previewVC;
  1361. [self.navigationController pushViewController:previewVC animated:YES];
  1362. }else {
  1363. if (!self.manager.configuration.singleJumpEdit) {
  1364. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1365. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1366. if (HX_IOS9Earlier) {
  1367. previewVC.photoViewController = self;
  1368. }
  1369. previewVC.delegate = self;
  1370. previewVC.modelArray = self.previewArray;
  1371. previewVC.manager = self.manager;
  1372. previewVC.currentModelIndex = currentIndex;
  1373. self.navigationController.delegate = previewVC;
  1374. [self.navigationController pushViewController:previewVC animated:YES];
  1375. }else {
  1376. if (cell.model.subType == HXPhotoModelMediaSubTypePhoto) {
  1377. if (self.manager.configuration.useWxPhotoEdit) {
  1378. HX_PhotoEditViewController *vc = [[HX_PhotoEditViewController alloc] initWithConfiguration:self.manager.configuration.photoEditConfigur];
  1379. vc.photoModel = cell.model;
  1380. vc.delegate = self;
  1381. vc.onlyCliping = YES;
  1382. vc.supportRotation = YES;
  1383. vc.isAutoBack = NO;
  1384. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1385. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1386. [self presentViewController:vc animated:YES completion:nil];
  1387. }else {
  1388. HXPhotoEditViewController *vc = [[HXPhotoEditViewController alloc] init];
  1389. vc.isInside = YES;
  1390. vc.model = cell.model;
  1391. vc.delegate = self;
  1392. vc.manager = self.manager;
  1393. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1394. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1395. [self presentViewController:vc animated:YES completion:nil];
  1396. }
  1397. }else {
  1398. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1399. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1400. if (HX_IOS9Earlier) {
  1401. previewVC.photoViewController = self;
  1402. }
  1403. previewVC.delegate = self;
  1404. previewVC.modelArray = self.previewArray;
  1405. previewVC.manager = self.manager;
  1406. previewVC.currentModelIndex = currentIndex;
  1407. self.navigationController.delegate = previewVC;
  1408. [self.navigationController pushViewController:previewVC animated:YES];
  1409. }
  1410. }
  1411. }
  1412. }
  1413. }
  1414. - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
  1415. if ([cell isKindOfClass:[HXPhotoViewCell class]]) {
  1416. [(HXPhotoViewCell *)cell cancelRequest];
  1417. }
  1418. }
  1419. - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
  1420. if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
  1421. if (self.manager.configuration.showBottomPhotoDetail) {
  1422. HXPhotoViewSectionFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"sectionFooterId" forIndexPath:indexPath];
  1423. footerView.textColor = self.manager.configuration.photoListBottomPhotoCountTextColor;
  1424. footerView.bgColor = self.manager.configuration.photoListViewBgColor;
  1425. footerView.photoCount = self.photoCount;
  1426. footerView.videoCount = self.videoCount;
  1427. self.footerView = footerView;
  1428. return footerView;
  1429. }
  1430. }
  1431. return [UICollectionReusableView new];
  1432. }
  1433. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
  1434. return CGSizeZero;
  1435. }
  1436. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
  1437. return self.manager.configuration.showBottomPhotoDetail ? CGSizeMake(self.view.hx_w, 50) : CGSizeZero;
  1438. }
  1439. - (UIViewController *)previewViewControlerWithIndexPath:(NSIndexPath *)indexPath {
  1440. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1441. if (!cell ||
  1442. cell.model.type == HXPhotoModelMediaTypeCamera ||
  1443. cell.model.type == HXPhotoModelMediaTypeLimit ||
  1444. cell.model.isICloud) {
  1445. return nil;
  1446. }
  1447. if (cell.model.networkPhotoUrl) {
  1448. if (cell.model.downloadError) {
  1449. return nil;
  1450. }
  1451. if (!cell.model.downloadComplete) {
  1452. return nil;
  1453. }
  1454. }
  1455. HXPhotoModel *_model = cell.model;
  1456. HXPhoto3DTouchViewController *vc = [[HXPhoto3DTouchViewController alloc] init];
  1457. vc.model = _model;
  1458. vc.indexPath = indexPath;
  1459. vc.image = cell.imageView.image;
  1460. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1461. HXWeakSelf
  1462. vc.downloadImageComplete = ^(HXPhoto3DTouchViewController *vc, HXPhotoModel *model) {
  1463. if (!model.loadOriginalImage) {
  1464. HXPhotoViewCell *myCell = (HXPhotoViewCell *)[weakSelf.collectionView cellForItemAtIndexPath:vc.indexPath];
  1465. if (myCell) {
  1466. [myCell resetNetworkImage];
  1467. }
  1468. }
  1469. };
  1470. vc.preferredContentSize = _model.previewViewSize;
  1471. return vc;
  1472. }
  1473. - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
  1474. NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:location];
  1475. if (!indexPath) {
  1476. return nil;
  1477. }
  1478. if (![[self.collectionView cellForItemAtIndexPath:indexPath] isKindOfClass:[HXPhotoViewCell class]]) {
  1479. return nil;
  1480. }
  1481. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1482. if (!cell ||
  1483. cell.model.type == HXPhotoModelMediaTypeCamera ||
  1484. cell.model.type == HXPhotoModelMediaTypeLimit ||
  1485. cell.model.isICloud) {
  1486. return nil;
  1487. }
  1488. if (cell.model.networkPhotoUrl) {
  1489. if (cell.model.downloadError) {
  1490. return nil;
  1491. }
  1492. if (!cell.model.downloadComplete) {
  1493. return nil;
  1494. }
  1495. }
  1496. //设置突出区域
  1497. previewingContext.sourceRect = [self.collectionView cellForItemAtIndexPath:indexPath].frame;
  1498. return [self previewViewControlerWithIndexPath:indexPath];
  1499. }
  1500. - (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
  1501. [self pushPreviewControler:viewControllerToCommit];
  1502. }
  1503. - (void)pushPreviewControler:(UIViewController *)viewController {
  1504. HXPhoto3DTouchViewController *vc = (HXPhoto3DTouchViewController *)viewController;
  1505. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:vc.indexPath];
  1506. if (!self.manager.configuration.singleSelected) {
  1507. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1508. if (HX_IOS9Earlier) {
  1509. previewVC.photoViewController = self;
  1510. }
  1511. previewVC.delegate = self;
  1512. previewVC.modelArray = self.previewArray;
  1513. previewVC.manager = self.manager;
  1514. #if HasSDWebImage
  1515. cell.model.tempImage = vc.sdImageView.image;
  1516. #elif HasYYKitOrWebImage
  1517. cell.model.tempImage = vc.animatedImageView.image;
  1518. #else
  1519. cell.model.tempImage = vc.imageView.image;
  1520. #endif
  1521. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1522. previewVC.currentModelIndex = currentIndex;
  1523. self.navigationController.delegate = previewVC;
  1524. [self.navigationController pushViewController:previewVC animated:NO];
  1525. }else {
  1526. if (!self.manager.configuration.singleJumpEdit) {
  1527. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1528. if (HX_IOS9Earlier) {
  1529. previewVC.photoViewController = self;
  1530. }
  1531. previewVC.delegate = self;
  1532. previewVC.modelArray = self.previewArray;
  1533. previewVC.manager = self.manager;
  1534. #if HasSDWebImage
  1535. cell.model.tempImage = vc.sdImageView.image;
  1536. #elif HasYYKitOrWebImage
  1537. cell.model.tempImage = vc.animatedImageView.image;
  1538. #else
  1539. cell.model.tempImage = vc.imageView.image;
  1540. #endif
  1541. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1542. previewVC.currentModelIndex = currentIndex;
  1543. self.navigationController.delegate = previewVC;
  1544. [self.navigationController pushViewController:previewVC animated:NO];
  1545. }else {
  1546. if (cell.model.subType == HXPhotoModelMediaSubTypePhoto) {
  1547. if (self.manager.configuration.useWxPhotoEdit) {
  1548. // HX_PhotoEditViewController *vc = [[HX_PhotoEditViewController alloc] initWithConfiguration:self.manager.configuration.photoEditConfigur];
  1549. // vc.photoModel = cell.model;
  1550. // vc.delegate = self;
  1551. // vc.onlyCliping = YES;
  1552. // vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1553. // vc.modalPresentationCapturesStatusBarAppearance = YES;
  1554. // [self presentViewController:vc animated:NO completion:nil];
  1555. }else {
  1556. HXPhotoEditViewController *vc = [[HXPhotoEditViewController alloc] init];
  1557. vc.model = cell.model;
  1558. vc.delegate = self;
  1559. vc.manager = self.manager;
  1560. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1561. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1562. [self presentViewController:vc animated:NO completion:nil];
  1563. }
  1564. }else {
  1565. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1566. if (HX_IOS9Earlier) {
  1567. previewVC.photoViewController = self;
  1568. }
  1569. previewVC.delegate = self;
  1570. previewVC.modelArray = self.previewArray;
  1571. previewVC.manager = self.manager;
  1572. #if HasSDWebImage
  1573. cell.model.tempImage = vc.sdImageView.image;
  1574. #elif HasYYKitOrWebImage
  1575. cell.model.tempImage = vc.animatedImageView.image;
  1576. #else
  1577. cell.model.tempImage = vc.imageView.image;
  1578. #endif
  1579. NSInteger currentIndex = [self.previewArray indexOfObject:cell.model];
  1580. previewVC.currentModelIndex = currentIndex;
  1581. self.navigationController.delegate = previewVC;
  1582. [self.navigationController pushViewController:previewVC animated:NO];
  1583. }
  1584. }
  1585. }
  1586. }
  1587. #pragma mark - < HXPhotoViewCellDelegate >
  1588. - (void)photoViewCellRequestICloudAssetComplete:(HXPhotoViewCell *)cell {
  1589. if (cell.model.dateCellIsVisible) {
  1590. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:cell.model] inSection:0];
  1591. if (indexPath) {
  1592. [self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
  1593. }
  1594. [self.manager addICloudModel:cell.model];
  1595. }
  1596. }
  1597. - (void)photoViewCell:(HXPhotoViewCell *)cell didSelectBtn:(UIButton *)selectBtn {
  1598. if (selectBtn.selected) {
  1599. if (cell.model.type != HXPhotoModelMediaTypeCameraVideo &&
  1600. cell.model.type != HXPhotoModelMediaTypeCameraPhoto) {
  1601. cell.model.thumbPhoto = nil;
  1602. cell.model.previewPhoto = nil;
  1603. }
  1604. [self.manager beforeSelectedListdeletePhotoModel:cell.model];
  1605. cell.model.selectIndexStr = @"";
  1606. cell.selectMaskLayer.hidden = YES;
  1607. selectBtn.selected = NO;
  1608. }else {
  1609. if (self.manager.shouldSelectModel) {
  1610. NSString *str = self.manager.shouldSelectModel(cell.model);
  1611. if (str) {
  1612. [self.view hx_showImageHUDText: [NSBundle hx_localizedStringForKey:str]];
  1613. return;
  1614. }
  1615. }
  1616. NSString *str = [self.manager maximumOfJudgment:cell.model];
  1617. if (str) {
  1618. if ([str isEqualToString:@"selectVideoBeyondTheLimitTimeAutoEdit"]) {
  1619. [self jumpVideoEditWithModel:cell.model];
  1620. }else {
  1621. [self.view hx_showImageHUDText:str];
  1622. }
  1623. return;
  1624. }
  1625. if (cell.model.type != HXPhotoModelMediaTypeCameraVideo &&
  1626. cell.model.type != HXPhotoModelMediaTypeCameraPhoto) {
  1627. cell.model.thumbPhoto = cell.imageView.image;
  1628. cell.model.previewPhoto = cell.imageView.image;
  1629. }
  1630. [self.manager beforeSelectedListAddPhotoModel:cell.model];
  1631. cell.selectMaskLayer.hidden = NO;
  1632. selectBtn.selected = YES;
  1633. [selectBtn setTitle:cell.model.selectIndexStr forState:UIControlStateSelected];
  1634. CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
  1635. anim.duration = 0.25;
  1636. anim.values = @[@(1.2),@(0.8),@(1.1),@(0.9),@(1.0)];
  1637. [selectBtn.layer addAnimation:anim forKey:@""];
  1638. }
  1639. NSMutableArray *indexPathList = [NSMutableArray array];
  1640. if (!selectBtn.selected) {
  1641. for (HXPhotoModel *model in [self.manager selectedArray]) {
  1642. if (model.currentAlbumIndex == self.albumModel.index) {
  1643. if (model.dateCellIsVisible) {
  1644. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:model] inSection:0];
  1645. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1646. if (cell && ![cell.selectBtn.currentTitle isEqualToString:model.selectIndexStr] &&
  1647. ![indexPathList containsObject:indexPath]) {
  1648. [indexPathList addObject:indexPath];
  1649. }
  1650. }
  1651. }
  1652. }
  1653. }
  1654. [indexPathList addObjectsFromArray:[self getVisibleVideoCellIndexPathsWithCurrentIndexPaths:indexPathList]];
  1655. if (indexPathList.count) {
  1656. [self.collectionView reloadItemsAtIndexPaths:indexPathList];
  1657. }
  1658. self.bottomView.selectCount = [self.manager selectedCount];
  1659. if ([self.delegate respondsToSelector:@selector(photoViewControllerDidChangeSelect:selected:)]) {
  1660. [self.delegate photoViewControllerDidChangeSelect:cell.model selected:selectBtn.selected];
  1661. }
  1662. }
  1663. #pragma mark - < HXPhotoPreviewViewControllerDelegate >
  1664. - (void)photoPreviewCellDownloadImageComplete:(HXPhotoPreviewViewController *)previewController model:(HXPhotoModel *)model {
  1665. if (model.dateCellIsVisible && !model.loadOriginalImage) {
  1666. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:model] inSection:0];
  1667. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1668. if (cell) {
  1669. [cell resetNetworkImage];
  1670. }
  1671. }
  1672. }
  1673. - (void)photoPreviewDownLoadICloudAssetComplete:(HXPhotoPreviewViewController *)previewController model:(HXPhotoModel *)model {
  1674. if (model.iCloudRequestID) {
  1675. [[PHImageManager defaultManager] cancelImageRequest:model.iCloudRequestID];
  1676. }
  1677. if (model.dateCellIsVisible) {
  1678. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:model] inSection:0];
  1679. [self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
  1680. }
  1681. [self.manager addICloudModel:model];
  1682. }
  1683. - (void)photoPreviewControllerDidSelect:(HXPhotoPreviewViewController *)previewController model:(HXPhotoModel *)model {
  1684. NSMutableArray *indexPathList = [NSMutableArray array];
  1685. if (model.currentAlbumIndex == self.albumModel.index) {
  1686. [indexPathList addObject:[NSIndexPath indexPathForItem:[self dateItem:model] inSection:0]];
  1687. }
  1688. if (!model.selected) {
  1689. NSInteger index = 0;
  1690. for (HXPhotoModel *subModel in [self.manager selectedArray]) {
  1691. if (subModel.currentAlbumIndex == self.albumModel.index && subModel.dateCellIsVisible) {
  1692. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[self dateItem:subModel] inSection:0];
  1693. HXPhotoViewCell *cell = (HXPhotoViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
  1694. if (cell && ![cell.selectBtn.currentTitle isEqualToString:model.selectIndexStr] &&
  1695. ![indexPathList containsObject:indexPath]) {
  1696. [indexPathList addObject:indexPath];
  1697. }
  1698. }
  1699. index++;
  1700. }
  1701. }
  1702. [indexPathList addObjectsFromArray:[self getVisibleVideoCellIndexPathsWithCurrentIndexPaths:indexPathList]];
  1703. if (indexPathList.count) {
  1704. [self.collectionView reloadItemsAtIndexPaths:indexPathList];
  1705. }
  1706. self.bottomView.selectCount = [self.manager selectedCount];
  1707. if ([self.delegate respondsToSelector:@selector(photoViewControllerDidChangeSelect:selected:)]) {
  1708. [self.delegate photoViewControllerDidChangeSelect:model selected:model.selected];
  1709. }
  1710. }
  1711. - (void)photoPreviewControllerDidDone:(HXPhotoPreviewViewController *)previewController {
  1712. [self photoBottomViewDidDoneBtn];
  1713. }
  1714. - (void)photoPreviewDidEditClick:(HXPhotoPreviewViewController *)previewController model:(HXPhotoModel *)model beforeModel:(HXPhotoModel *)beforeModel {
  1715. if (model.subType == HXPhotoModelMediaSubTypePhoto) {
  1716. if (self.manager.configuration.useWxPhotoEdit) {
  1717. [self.collectionView reloadData];
  1718. [self.bottomView requestPhotosBytes];
  1719. return;
  1720. }
  1721. }
  1722. model.currentAlbumIndex = self.albumModel.index;
  1723. [self photoPreviewControllerDidSelect:nil model:beforeModel];
  1724. [self collectionViewAddModel:model beforeModel:beforeModel];
  1725. // [self photoBottomViewDidDoneBtn];
  1726. }
  1727. - (void)photoPreviewSingleSelectedClick:(HXPhotoPreviewViewController *)previewController model:(HXPhotoModel *)model {
  1728. [self.manager beforeSelectedListAddPhotoModel:model];
  1729. [self photoBottomViewDidDoneBtn];
  1730. }
  1731. #pragma mark - < HX_PhotoEditViewControllerDelegate >
  1732. - (void)photoEditingController:(HX_PhotoEditViewController *)photoEditingVC didFinishPhotoEdit:(HXPhotoEdit *)photoEdit photoModel:(HXPhotoModel *)photoModel {
  1733. if (self.manager.configuration.singleSelected) {
  1734. #pragma clang diagnostic push
  1735. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
  1736. [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
  1737. #pragma clang diagnostic pop
  1738. self.isNewEditDismiss = YES;
  1739. [self.manager beforeSelectedListAddPhotoModel:photoModel];
  1740. [self photoBottomViewDidDoneBtn];
  1741. return;
  1742. }
  1743. [self.collectionView reloadData];
  1744. [self.bottomView requestPhotosBytes];
  1745. if (photoEditingVC.isAutoBack) {
  1746. return;
  1747. }
  1748. if (photoEditingVC.navigationController.viewControllers.count <= 1) {
  1749. [photoEditingVC dismissViewControllerAnimated:YES completion:nil];
  1750. }else {
  1751. [photoEditingVC.navigationController popViewControllerAnimated:YES];
  1752. }
  1753. }
  1754. - (void)photoEditingControllerDidCancel:(HX_PhotoEditViewController *)photoEditingVC {
  1755. if (photoEditingVC.isAutoBack) {
  1756. return;
  1757. }
  1758. if (photoEditingVC.navigationController.viewControllers.count <= 1) {
  1759. [photoEditingVC dismissViewControllerAnimated:YES completion:nil];
  1760. }else {
  1761. [photoEditingVC.navigationController popViewControllerAnimated:YES];
  1762. }
  1763. }
  1764. #pragma mark - < HXPhotoEditViewControllerDelegate >
  1765. - (void)photoEditViewControllerDidClipClick:(HXPhotoEditViewController *)photoEditViewController beforeModel:(HXPhotoModel *)beforeModel afterModel:(HXPhotoModel *)afterModel {
  1766. if (self.manager.configuration.singleSelected) {
  1767. [self.manager beforeSelectedListAddPhotoModel:afterModel];
  1768. [self photoBottomViewDidDoneBtn];
  1769. return;
  1770. }
  1771. [self.manager beforeSelectedListdeletePhotoModel:beforeModel];
  1772. [self photoPreviewControllerDidSelect:nil model:beforeModel];
  1773. afterModel.currentAlbumIndex = self.albumModel.index;
  1774. [self.manager beforeListAddCameraTakePicturesModel:afterModel];
  1775. [self collectionViewAddModel:afterModel beforeModel:beforeModel];
  1776. }
  1777. #pragma mark - < HXVideoEditViewControllerDelegate >
  1778. - (void)videoEditViewControllerDidDoneClick:(HXVideoEditViewController *)videoEditViewController beforeModel:(HXPhotoModel *)beforeModel afterModel:(HXPhotoModel *)afterModel {
  1779. [self photoEditViewControllerDidClipClick:nil beforeModel:beforeModel afterModel:afterModel];
  1780. if (afterModel.needHideSelectBtn && !self.manager.configuration.singleSelected) {
  1781. self.isNewEditDismiss = YES;
  1782. [self.manager beforeSelectedListAddPhotoModel:afterModel];
  1783. [self photoBottomViewDidDoneBtn];
  1784. }
  1785. }
  1786. #pragma mark - < HXPhotoBottomViewDelegate >
  1787. - (void)photoBottomViewDidPreviewBtn {
  1788. if (self.navigationController.topViewController != self || [self.manager selectedCount] == 0) {
  1789. return;
  1790. }
  1791. HXPhotoPreviewViewController *previewVC = [[HXPhotoPreviewViewController alloc] init];
  1792. if (HX_IOS9Earlier) {
  1793. previewVC.photoViewController = self;
  1794. }
  1795. previewVC.delegate = self;
  1796. previewVC.modelArray = [NSMutableArray arrayWithArray:[self.manager selectedArray]];
  1797. previewVC.manager = self.manager;
  1798. previewVC.currentModelIndex = 0;
  1799. previewVC.selectPreview = YES;
  1800. self.navigationController.delegate = previewVC;
  1801. [self.navigationController pushViewController:previewVC animated:YES];
  1802. }
  1803. - (void)photoBottomViewDidDoneBtn {
  1804. if (self.manager.configuration.requestImageAfterFinishingSelection) {
  1805. if ([self.navigationController.viewControllers.lastObject isKindOfClass:[HXPhotoPreviewViewController class]]) {
  1806. self.navigationController.navigationBar.userInteractionEnabled = NO;
  1807. }
  1808. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  1809. if (self.manager.configuration.photoListTitleView) {
  1810. self.navigationController.navigationItem.titleView.userInteractionEnabled = NO;
  1811. }else {
  1812. self.albumTitleView.userInteractionEnabled = NO;
  1813. }
  1814. }
  1815. self.navigationController.viewControllers.lastObject.view.userInteractionEnabled = NO;
  1816. [self.navigationController.viewControllers.lastObject.view hx_showLoadingHUDText:nil];
  1817. HXWeakSelf
  1818. BOOL requestOriginal = self.manager.original;
  1819. if (self.manager.configuration.hideOriginalBtn) {
  1820. requestOriginal = self.manager.configuration.requestOriginalImage;
  1821. }
  1822. // if (requestOriginal) {
  1823. [self.manager.selectedArray hx_requestImageSeparatelyWithOriginal:requestOriginal completion:^(NSArray<UIImage *> * _Nullable imageArray, NSArray<HXPhotoModel *> * _Nullable errorArray) {
  1824. if (!weakSelf) {
  1825. return;
  1826. }
  1827. [weakSelf afterFinishingGetVideoURL];
  1828. }];
  1829. // }else {
  1830. // [self.manager.selectedArray hx_requestImageWithOriginal:requestOriginal completion:^(NSArray<UIImage *> * _Nullable imageArray, NSArray<HXPhotoModel *> * _Nullable errorArray) {
  1831. // if (!weakSelf) {
  1832. // return;
  1833. // }
  1834. // [weakSelf afterFinishingGetVideoURL];
  1835. // }];
  1836. // }
  1837. return;
  1838. }
  1839. [self dismissVC];
  1840. }
  1841. - (void)afterFinishingGetVideoURL {
  1842. NSArray *videoArray = self.manager.selectedVideoArray;
  1843. if (videoArray.count) {
  1844. BOOL requestOriginal = self.manager.original;
  1845. if (self.manager.configuration.hideOriginalBtn) {
  1846. requestOriginal = self.manager.configuration.requestOriginalImage;
  1847. }
  1848. HXWeakSelf
  1849. __block NSInteger videoCount = videoArray.count;
  1850. __block NSInteger videoIndex = 0;
  1851. BOOL endOriginal = self.manager.configuration.exportVideoURLForHighestQuality ? requestOriginal : NO;
  1852. for (HXPhotoModel *pm in videoArray) {
  1853. [pm exportVideoWithPresetName:endOriginal ? AVAssetExportPresetHighestQuality : AVAssetExportPresetMediumQuality startRequestICloud:nil iCloudProgressHandler:nil exportProgressHandler:nil success:^(NSURL * _Nullable videoURL, HXPhotoModel * _Nullable model) {
  1854. if (!weakSelf) {
  1855. return;
  1856. }
  1857. videoIndex++;
  1858. if (videoIndex == videoCount) {
  1859. [weakSelf dismissVC];
  1860. }
  1861. } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) {
  1862. if (!weakSelf) {
  1863. return;
  1864. }
  1865. videoIndex++;
  1866. if (videoIndex == videoCount) {
  1867. [weakSelf dismissVC];
  1868. }
  1869. }];
  1870. }
  1871. }else {
  1872. [self dismissVC];
  1873. }
  1874. }
  1875. - (void)dismissVC {
  1876. [self.manager selectedListTransformAfter];
  1877. if (self.manager.configuration.albumShowMode == HXPhotoAlbumShowModePopup) {
  1878. if (self.manager.configuration.photoListChangeTitleViewSelected) {
  1879. self.manager.configuration.photoListChangeTitleViewSelected(NO);
  1880. }
  1881. if (self.manager.configuration.photoListTitleView) {
  1882. self.navigationItem.titleView.userInteractionEnabled = YES;
  1883. }else {
  1884. self.albumTitleView.userInteractionEnabled = YES;
  1885. }
  1886. }
  1887. self.navigationController.navigationBar.userInteractionEnabled = YES;
  1888. self.navigationController.viewControllers.lastObject.view.userInteractionEnabled = YES;
  1889. [self.navigationController.viewControllers.lastObject.view hx_handleLoading];
  1890. [self cleanSelectedList];
  1891. if (self.manager.configuration.singleSelected) {
  1892. [self.manager clearSelectedList];
  1893. }
  1894. self.manager.selectPhotoing = NO;
  1895. BOOL selectPhotoFinishDismissAnimated = self.manager.selectPhotoFinishDismissAnimated;
  1896. if (self.isNewEditDismiss || [self.presentedViewController isKindOfClass:[HX_PhotoEditViewController class]] || [self.presentedViewController isKindOfClass:[HXVideoEditViewController class]]) {
  1897. [self.presentingViewController dismissViewControllerAnimated:selectPhotoFinishDismissAnimated completion:^{
  1898. if ([self.delegate respondsToSelector:@selector(photoViewControllerFinishDismissCompletion:)]) {
  1899. [self.delegate photoViewControllerFinishDismissCompletion:self];
  1900. }
  1901. }];
  1902. }else {
  1903. [self dismissViewControllerAnimated:selectPhotoFinishDismissAnimated completion:^{
  1904. if ([self.delegate respondsToSelector:@selector(photoViewControllerFinishDismissCompletion:)]) {
  1905. [self.delegate photoViewControllerFinishDismissCompletion:self];
  1906. }
  1907. }];
  1908. }
  1909. }
  1910. - (void)photoBottomViewDidEditBtn {
  1911. HXPhotoModel *model = self.manager.selectedArray.firstObject;
  1912. if (model.networkPhotoUrl) {
  1913. if (model.downloadError) {
  1914. [self.view hx_showImageHUDText:[NSBundle hx_localizedStringForKey:@"下载失败"]];
  1915. return;
  1916. }
  1917. if (!model.downloadComplete) {
  1918. [self.view hx_showImageHUDText:[NSBundle hx_localizedStringForKey:@"照片正在下载"]];
  1919. return;
  1920. }
  1921. }
  1922. if (model.type == HXPhotoModelMediaTypePhotoGif ||
  1923. model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeNetWorkGif) {
  1924. if (model.photoEdit) {
  1925. [self jumpEditViewControllerWithModel:model];
  1926. }else {
  1927. HXWeakSelf
  1928. hx_showAlert(self, [NSBundle hx_localizedStringForKey:@"编辑后,GIF将会变为静态图,确定继续吗?"], nil, [NSBundle hx_localizedStringForKey:@"取消"], [NSBundle hx_localizedStringForKey:@"确定"], nil, ^{
  1929. [weakSelf jumpEditViewControllerWithModel:model];
  1930. });
  1931. }
  1932. return;
  1933. }
  1934. if (model.type == HXPhotoModelMediaTypeLivePhoto) {
  1935. if (model.photoEdit) {
  1936. [self jumpEditViewControllerWithModel:model];
  1937. }else {
  1938. HXWeakSelf
  1939. hx_showAlert(self, [NSBundle hx_localizedStringForKey:@"编辑后,LivePhoto将会变为静态图,确定继续吗?"], nil, [NSBundle hx_localizedStringForKey:@"取消"], [NSBundle hx_localizedStringForKey:@"确定"], nil, ^{
  1940. [weakSelf jumpEditViewControllerWithModel:model];
  1941. });
  1942. }
  1943. return;
  1944. }
  1945. [self jumpEditViewControllerWithModel:model];
  1946. }
  1947. - (void)jumpEditViewControllerWithModel:(HXPhotoModel *)model {
  1948. if (model.subType == HXPhotoModelMediaSubTypePhoto) {
  1949. if (self.manager.configuration.replacePhotoEditViewController) {
  1950. #pragma mark - < 替换图片编辑 >
  1951. if (self.manager.configuration.shouldUseEditAsset) {
  1952. self.manager.configuration.shouldUseEditAsset(self, NO,self.manager, model);
  1953. }
  1954. HXWeakSelf
  1955. self.manager.configuration.usePhotoEditComplete = ^(HXPhotoModel *beforeModel, HXPhotoModel *afterModel) {
  1956. [weakSelf photoEditViewControllerDidClipClick:nil beforeModel:beforeModel afterModel:afterModel];
  1957. };
  1958. }else {
  1959. if (self.manager.configuration.useWxPhotoEdit) {
  1960. HX_PhotoEditViewController *vc = [[HX_PhotoEditViewController alloc] initWithConfiguration:self.manager.configuration.photoEditConfigur];
  1961. vc.photoModel = self.manager.selectedPhotoArray.firstObject;
  1962. vc.delegate = self;
  1963. vc.supportRotation = YES;
  1964. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1965. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1966. [self presentViewController:vc animated:YES completion:nil];
  1967. }else {
  1968. HXPhotoEditViewController *vc = [[HXPhotoEditViewController alloc] init];
  1969. vc.isInside = YES;
  1970. vc.model = self.manager.selectedPhotoArray.firstObject;
  1971. vc.delegate = self;
  1972. vc.manager = self.manager;
  1973. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  1974. vc.modalPresentationCapturesStatusBarAppearance = YES;
  1975. [self presentViewController:vc animated:YES completion:nil];
  1976. }
  1977. }
  1978. }else if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  1979. if (self.manager.configuration.replaceVideoEditViewController) {
  1980. #pragma mark - < 替换视频编辑 >
  1981. if (self.manager.configuration.shouldUseEditAsset) {
  1982. self.manager.configuration.shouldUseEditAsset(self, NO, self.manager, model);
  1983. }
  1984. HXWeakSelf
  1985. self.manager.configuration.useVideoEditComplete = ^(HXPhotoModel *beforeModel, HXPhotoModel *afterModel) {
  1986. [weakSelf photoEditViewControllerDidClipClick:nil beforeModel:beforeModel afterModel:afterModel];
  1987. };
  1988. }else {
  1989. [self jumpVideoEditWithModel:self.manager.selectedVideoArray.firstObject];
  1990. }
  1991. }
  1992. }
  1993. - (void)jumpVideoEditWithModel:(HXPhotoModel *)model {
  1994. HXVideoEditViewController *vc = [[HXVideoEditViewController alloc] init];
  1995. vc.model = model;
  1996. vc.delegate = self;
  1997. vc.manager = self.manager;
  1998. vc.isInside = YES;
  1999. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  2000. vc.modalPresentationCapturesStatusBarAppearance = YES;
  2001. [self presentViewController:vc animated:YES completion:nil];
  2002. }
  2003. - (void)cleanSelectedList {
  2004. NSArray *allList;
  2005. NSArray *photoList;
  2006. NSArray *videoList;
  2007. BOOL isOriginal;
  2008. if (!self.manager.configuration.singleSelected) {
  2009. allList = self.manager.afterSelectedArray.copy;
  2010. photoList = self.manager.afterSelectedPhotoArray.copy;
  2011. videoList = self.manager.afterSelectedVideoArray.copy;
  2012. isOriginal = self.manager.afterOriginal;
  2013. }else {
  2014. allList = self.manager.selectedArray.copy;
  2015. photoList = self.manager.selectedPhotoArray.copy;
  2016. videoList = self.manager.selectedVideoArray.copy;
  2017. isOriginal = self.manager.original;
  2018. }
  2019. if ([self.delegate respondsToSelector:@selector(photoViewController:didDoneAllList:photos:videos:original:)]) {
  2020. [self.delegate photoViewController:self
  2021. didDoneAllList:allList
  2022. photos:photoList
  2023. videos:videoList
  2024. original:isOriginal];
  2025. }
  2026. if ([self.delegate respondsToSelector:@selector(photoViewController:didDoneWithResult:)]) {
  2027. HXPickerResult *result = [[HXPickerResult alloc] initWithModels:allList isOriginal:isOriginal];
  2028. [self.delegate photoViewController:self
  2029. didDoneWithResult:result];
  2030. }
  2031. if (self.doneBlock) {
  2032. self.doneBlock(allList, photoList, videoList, isOriginal, self, self.manager);
  2033. }
  2034. }
  2035. #pragma mark - < 懒加载 >
  2036. - (UILabel *)authorizationLb {
  2037. if (!_authorizationLb) {
  2038. _authorizationLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, self.view.hx_w, 100)];
  2039. _authorizationLb.text = [NSBundle hx_localizedStringForKey:@"无法访问照片\n请点击这里前往设置中允许访问照片"];
  2040. _authorizationLb.textAlignment = NSTextAlignmentCenter;
  2041. _authorizationLb.numberOfLines = 0;
  2042. UIColor *authorizationColor = self.manager.configuration.authorizationTipColor;
  2043. _authorizationLb.textColor = [HXPhotoCommon photoCommon].isDark ? [UIColor whiteColor] : authorizationColor;
  2044. _authorizationLb.font = [UIFont systemFontOfSize:15];
  2045. _authorizationLb.userInteractionEnabled = YES;
  2046. [_authorizationLb addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(goSetup)]];
  2047. }
  2048. return _authorizationLb;
  2049. }
  2050. - (void)goSetup {
  2051. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  2052. if (@available(iOS 10.0, *)) {
  2053. [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
  2054. }else {
  2055. [[UIApplication sharedApplication] openURL:url];
  2056. }
  2057. }
  2058. - (UIView *)albumBgView {
  2059. if (!_albumBgView) {
  2060. _albumBgView = [[UIView alloc] initWithFrame:self.view.bounds];
  2061. _albumBgView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
  2062. [_albumBgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didAlbumBgViewClick)]];
  2063. _albumBgView.hidden = YES;
  2064. }
  2065. return _albumBgView;
  2066. }
  2067. - (void)didAlbumBgViewClick {
  2068. if (self.manager.configuration.photoListChangeTitleViewSelected) {
  2069. self.manager.configuration.photoListChangeTitleViewSelected(NO);
  2070. }else {
  2071. [self.albumTitleView deSelect];
  2072. }
  2073. }
  2074. - (HXAlbumlistView *)albumView {
  2075. if (!_albumView) {
  2076. _albumView = [[HXAlbumlistView alloc] initWithManager:self.manager];
  2077. HXWeakSelf
  2078. _albumView.didSelectRowBlock = ^(HXAlbumModel *model) {
  2079. [weakSelf.hx_customNavigationController clearAssetCache];
  2080. if (weakSelf.manager.configuration.photoListChangeTitleViewSelected) {
  2081. weakSelf.manager.configuration.photoListChangeTitleViewSelected(NO);
  2082. [weakSelf albumTitleViewDidAction:NO];
  2083. }else {
  2084. [weakSelf.albumTitleView deSelect];
  2085. }
  2086. if (weakSelf.albumModel == model ||
  2087. [weakSelf.albumModel.localIdentifier isEqualToString:model.localIdentifier]) {
  2088. return;
  2089. }
  2090. weakSelf.albumModel = model;
  2091. if (weakSelf.manager.configuration.updatePhotoListTitle) {
  2092. weakSelf.manager.configuration.updatePhotoListTitle(model.albumName);
  2093. }else {
  2094. weakSelf.albumTitleView.model = model;
  2095. }
  2096. [weakSelf.hx_customNavigationController.view hx_showLoadingHUDText:nil];
  2097. weakSelf.collectionViewReloadCompletion = NO;
  2098. weakSelf.firstOn = NO;
  2099. [weakSelf startGetAllPhotoModel];
  2100. };
  2101. }
  2102. return _albumView;
  2103. }
  2104. - (HXAlbumTitleView *)albumTitleView {
  2105. if (!_albumTitleView) {
  2106. _albumTitleView = [[HXAlbumTitleView alloc] initWithManager:self.manager];
  2107. HXWeakSelf
  2108. _albumTitleView.didTitleViewBlock = ^(BOOL selected) {
  2109. [weakSelf albumTitleViewDidAction:selected];
  2110. };
  2111. }
  2112. return _albumTitleView;
  2113. }
  2114. - (void)albumTitleViewDidAction:(BOOL)selected {
  2115. if (!self.albumView.albumModelArray.count) {
  2116. return;
  2117. }
  2118. if (selected) {
  2119. if (!self.firstDidAlbumTitleView) {
  2120. HXAlbumModel *albumMd = self.albumView.albumModelArray.firstObject;
  2121. if (albumMd.realCount != self.photoCount + self.videoCount) {
  2122. albumMd.realCount = self.photoCount + self.videoCount;
  2123. HXPhotoModel *photoModel = self.previewArray.lastObject;
  2124. albumMd.realCoverAsset = photoModel.asset;
  2125. albumMd.needReloadCount = YES;
  2126. }
  2127. [self.albumView refreshCamearCount];
  2128. self.firstDidAlbumTitleView = YES;
  2129. }else {
  2130. BOOL needReload = self.albumModel.realCount != self.photoCount + self.videoCount;
  2131. if (!needReload && self.albumModel.realCount == 0) {
  2132. needReload = YES;
  2133. }
  2134. if (needReload) {
  2135. self.albumModel.realCount = self.photoCount + self.videoCount;
  2136. HXPhotoModel *photoModel = self.previewArray.lastObject;
  2137. self.albumModel.realCoverAsset = photoModel.asset;
  2138. self.albumModel.needReloadCount = YES;
  2139. [self.albumView reloadAlbumAssetCountWithAlbumModel:self.albumModel];
  2140. }
  2141. }
  2142. self.albumBgView.hidden = NO;
  2143. self.albumBgView.alpha = 0;
  2144. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
  2145. CGFloat navBarHeight = hxNavigationBarHeight;
  2146. if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown || HX_UI_IS_IPAD) {
  2147. navBarHeight = hxNavigationBarHeight;
  2148. }else if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft){
  2149. if ([UIApplication sharedApplication].statusBarHidden) {
  2150. navBarHeight = self.navigationController.navigationBar.hx_h;
  2151. }else {
  2152. navBarHeight = self.navigationController.navigationBar.hx_h + 20;
  2153. }
  2154. }
  2155. [self.albumView selectCellScrollToCenter];
  2156. if (self.manager.configuration.singleSelected) {
  2157. [UIView animateWithDuration:0.1 delay:0.15 options:0 animations:^{
  2158. self.albumView.alpha = 1;
  2159. } completion:nil];
  2160. }
  2161. [UIView animateWithDuration:0.25 animations:^{
  2162. self.albumBgView.alpha = 1;
  2163. self.albumView.hx_y = navBarHeight;
  2164. }];
  2165. }else {
  2166. if (self.manager.configuration.singleSelected) {
  2167. [UIView animateWithDuration:0.1 animations:^{
  2168. self.albumView.alpha = 0;
  2169. }];
  2170. }
  2171. [UIView animateWithDuration:0.25 animations:^{
  2172. self.albumBgView.alpha = 0;
  2173. self.albumView.hx_y = -CGRectGetMaxY(self.albumView.frame);
  2174. } completion:^(BOOL finished) {
  2175. if (!selected) {
  2176. self.albumBgView.hidden = YES;
  2177. }
  2178. }];
  2179. }
  2180. }
  2181. - (HXPhotoLimitView *)limitView {
  2182. if (!_limitView) {
  2183. CGFloat y = self.view.hx_h - hxBottomMargin - 15 - 40;
  2184. if (!self.manager.configuration.singleSelected) {
  2185. y = self.view.hx_h - self.bottomView.hx_h - 10 - 40;
  2186. }
  2187. _limitView = [[HXPhotoLimitView alloc] initWithFrame:CGRectMake(12, y, self.view.hx_w - 24, 40)];
  2188. [_limitView setBlurEffectStyle:self.manager.configuration.photoListLimitBlurStyle];
  2189. [_limitView setTextColor:self.manager.configuration.photoListLimitTextColor];
  2190. [_limitView setSettingColor:self.manager.configuration.photoListLimitSettingColor];
  2191. [_limitView setCloseColor:self.manager.configuration.photoListLimitCloseColor];
  2192. }
  2193. return _limitView;
  2194. }
  2195. - (HXPhotoBottomView *)bottomView {
  2196. if (!_bottomView) {
  2197. _bottomView = [[HXPhotoBottomView alloc] initWithFrame:CGRectMake(0, self.view.hx_h - 50 - hxBottomMargin, self.view.hx_w, 50 + hxBottomMargin)];
  2198. _bottomView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  2199. _bottomView.manager = self.manager;
  2200. _bottomView.delegate = self;
  2201. }
  2202. return _bottomView;
  2203. }
  2204. - (UICollectionView *)collectionView {
  2205. if (!_collectionView) {
  2206. CGFloat collectionHeight = self.view.hx_h;
  2207. _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.hx_w, collectionHeight) collectionViewLayout:self.flowLayout];
  2208. _collectionView.dataSource = self;
  2209. _collectionView.delegate = self;
  2210. _collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  2211. _collectionView.alwaysBounceVertical = YES;
  2212. [_collectionView registerClass:[HXPhotoViewCell class] forCellWithReuseIdentifier:@"HXPhotoViewCellID"];
  2213. [_collectionView registerClass:[HXPhotoCameraViewCell class] forCellWithReuseIdentifier:@"HXPhotoCameraViewCellId"];
  2214. [_collectionView registerClass:[HXPhotoLimitViewCell class] forCellWithReuseIdentifier:@"HXPhotoLimitViewCellId"];
  2215. [_collectionView registerClass:[HXPhotoViewSectionFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"sectionFooterId"];
  2216. #ifdef __IPHONE_11_0
  2217. if (@available(iOS 11.0, *)) {
  2218. _collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  2219. #else
  2220. if ((NO)) {
  2221. #endif
  2222. } else {
  2223. self.automaticallyAdjustsScrollViewInsets = NO;
  2224. }
  2225. }
  2226. return _collectionView;
  2227. }
  2228. - (UICollectionViewFlowLayout *)flowLayout {
  2229. if (!_flowLayout) {
  2230. _flowLayout = [[UICollectionViewFlowLayout alloc] init];
  2231. _flowLayout.minimumLineSpacing = 1;
  2232. _flowLayout.minimumInteritemSpacing = 1;
  2233. _flowLayout.sectionInset = UIEdgeInsetsMake(0.5, 0, 0.5, 0);
  2234. }
  2235. return _flowLayout;
  2236. }
  2237. @end
  2238. @interface HXPhotoCameraViewCell ()
  2239. @property (strong, nonatomic) UIButton *cameraBtn;
  2240. @property (strong, nonatomic) HXCustomCameraController *cameraController;
  2241. @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
  2242. @property (strong, nonatomic) UIVisualEffectView *effectView;
  2243. @property (strong, nonatomic) UIView *previewView;
  2244. @property (strong, nonatomic) UIImageView *tempCameraView;
  2245. @end
  2246. @implementation HXPhotoCameraViewCell
  2247. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  2248. [super traitCollectionDidChange:previousTraitCollection];
  2249. #ifdef __IPHONE_13_0
  2250. if (@available(iOS 13.0, *)) {
  2251. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  2252. if ([HXPhotoCommon photoCommon].isDark) {
  2253. self.cameraBtn.selected = YES;
  2254. }else {
  2255. self.cameraBtn.selected = self.startSession;
  2256. }
  2257. }
  2258. }
  2259. #endif
  2260. }
  2261. - (instancetype)initWithFrame:(CGRect)frame {
  2262. self = [super initWithFrame:frame];
  2263. if (self) {
  2264. [self setupUI];
  2265. }
  2266. return self;
  2267. }
  2268. - (void)setupUI {
  2269. self.startSession = NO;
  2270. [self.contentView addSubview:self.previewView];
  2271. [self.contentView addSubview:self.cameraBtn];
  2272. if ([HXPhotoCommon photoCommon].isDark) {
  2273. self.cameraBtn.selected = YES;
  2274. }
  2275. }
  2276. - (void)setBgColor:(UIColor *)bgColor {
  2277. _bgColor = bgColor;
  2278. self.backgroundColor = bgColor;
  2279. }
  2280. - (void)setCameraImage:(UIImage *)cameraImage {
  2281. _cameraImage = cameraImage;
  2282. if (self.startSession) return;
  2283. if (![UIImagePickerController isSourceTypeAvailable:
  2284. UIImagePickerControllerSourceTypeCamera]) {
  2285. return;
  2286. }
  2287. if ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != AVAuthorizationStatusAuthorized) {
  2288. return;
  2289. }
  2290. if (cameraImage) {
  2291. self.tempCameraView.image = cameraImage;
  2292. [self.previewView addSubview:self.tempCameraView];
  2293. [self.previewView addSubview:self.effectView];
  2294. self.cameraSelected = YES;
  2295. self.cameraBtn.selected = YES;
  2296. }
  2297. }
  2298. - (void)starRunning {
  2299. if (![UIImagePickerController isSourceTypeAvailable:
  2300. UIImagePickerControllerSourceTypeCamera]) {
  2301. return;
  2302. }
  2303. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  2304. if (authStatus != AVAuthorizationStatusAuthorized) {
  2305. return;
  2306. }
  2307. if (self.startSession) {
  2308. return;
  2309. }
  2310. self.startSession = YES;
  2311. HXWeakSelf
  2312. [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
  2313. if (granted) {
  2314. [weakSelf initSession];
  2315. }
  2316. }];
  2317. }
  2318. - (void)initSession {
  2319. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  2320. [self.cameraController initSeesion];
  2321. self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.cameraController.captureSession];
  2322. HXWeakSelf
  2323. [self.cameraController setupPreviewLayer:self.previewLayer startSessionCompletion:^(BOOL success) {
  2324. if (!weakSelf) {
  2325. return;
  2326. }
  2327. if (success) {
  2328. [weakSelf.cameraController.captureSession startRunning];
  2329. dispatch_async(dispatch_get_main_queue(), ^{
  2330. [weakSelf.previewView.layer insertSublayer:weakSelf.previewLayer atIndex:0];
  2331. weakSelf.previewLayer.frame = weakSelf.bounds;
  2332. weakSelf.cameraBtn.selected = YES;
  2333. if (weakSelf.tempCameraView.image) {
  2334. if (weakSelf.cameraSelected) {
  2335. [UIView animateWithDuration:0.25 animations:^{
  2336. weakSelf.tempCameraView.alpha = 0;
  2337. if (HX_IOS9Later) {
  2338. [weakSelf.effectView setEffect:nil];
  2339. }else {
  2340. weakSelf.effectView.alpha = 0;
  2341. }
  2342. } completion:^(BOOL finished) {
  2343. [weakSelf.tempCameraView removeFromSuperview];
  2344. [weakSelf.effectView removeFromSuperview];
  2345. }];
  2346. }
  2347. }
  2348. });
  2349. }
  2350. }];
  2351. });
  2352. }
  2353. - (void)stopRunning {
  2354. if (![UIImagePickerController isSourceTypeAvailable:
  2355. UIImagePickerControllerSourceTypeCamera]) {
  2356. return;
  2357. }
  2358. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  2359. if (authStatus != AVAuthorizationStatusAuthorized) {
  2360. return;
  2361. }
  2362. if (!_cameraController) {
  2363. return;
  2364. }
  2365. [self.cameraController stopSession];
  2366. }
  2367. - (void)setModel:(HXPhotoModel *)model {
  2368. _model = model;
  2369. if (!model.thumbPhoto) {
  2370. model.thumbPhoto = [UIImage hx_imageNamed:model.cameraNormalImageNamed];
  2371. }
  2372. if (!model.previewPhoto) {
  2373. model.previewPhoto = [UIImage hx_imageNamed:model.cameraPreviewImageNamed];
  2374. }
  2375. [self.cameraBtn setImage:model.thumbPhoto forState:UIControlStateNormal];
  2376. [self.cameraBtn setImage:model.previewPhoto forState:UIControlStateSelected];
  2377. }
  2378. - (void)layoutSubviews {
  2379. [super layoutSubviews];
  2380. self.cameraBtn.frame = self.bounds;
  2381. self.previewView.frame = self.bounds;
  2382. self.effectView.frame = self.bounds;
  2383. self.tempCameraView.frame = self.bounds;
  2384. }
  2385. - (void)willRemoveSubview:(UIView *)subview {
  2386. [super willRemoveSubview:subview];
  2387. [subview.layer removeAllAnimations];
  2388. }
  2389. - (void)dealloc {
  2390. [self stopRunning];
  2391. }
  2392. - (UIButton *)cameraBtn {
  2393. if (!_cameraBtn) {
  2394. _cameraBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  2395. _cameraBtn.userInteractionEnabled = NO;
  2396. }
  2397. return _cameraBtn;
  2398. }
  2399. - (UIVisualEffectView *)effectView {
  2400. if (!_effectView) {
  2401. UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
  2402. _effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
  2403. }
  2404. return _effectView;
  2405. }
  2406. - (UIView *)previewView {
  2407. if (!_previewView) {
  2408. _previewView = [[UIView alloc] init];
  2409. }
  2410. return _previewView;
  2411. }
  2412. - (HXCustomCameraController *)cameraController {
  2413. if (!_cameraController) {
  2414. _cameraController = [[HXCustomCameraController alloc] init];
  2415. }
  2416. return _cameraController;
  2417. }
  2418. - (UIImageView *)tempCameraView {
  2419. if (!_tempCameraView) {
  2420. _tempCameraView = [[UIImageView alloc] init];
  2421. _tempCameraView.contentMode = UIViewContentModeScaleAspectFill;
  2422. _tempCameraView.clipsToBounds = YES;
  2423. }
  2424. return _tempCameraView;
  2425. }
  2426. @end
  2427. @interface HXPhotoLimitViewCell()
  2428. @property (strong, nonatomic) CAShapeLayer *lineLayer;
  2429. @property (strong, nonatomic) UILabel *textLb;
  2430. @end
  2431. @implementation HXPhotoLimitViewCell
  2432. - (CAShapeLayer *)lineLayer {
  2433. if (!_lineLayer) {
  2434. _lineLayer = [CAShapeLayer layer];
  2435. _lineLayer.lineWidth = 4;
  2436. _lineLayer.lineCap = kCALineCapRound;
  2437. _lineLayer.fillColor = [UIColor clearColor].CGColor;
  2438. _lineLayer.contentsScale = [UIScreen mainScreen].scale;
  2439. }
  2440. return _lineLayer;
  2441. }
  2442. - (UILabel *)textLb {
  2443. if (!_textLb) {
  2444. _textLb = [[UILabel alloc] init];
  2445. _textLb.text = [NSBundle hx_localizedStringForKey:@"更多"];
  2446. _textLb.textAlignment = NSTextAlignmentCenter;
  2447. _textLb.adjustsFontSizeToFitWidth = YES;
  2448. }
  2449. return _textLb;
  2450. }
  2451. - (instancetype)initWithFrame:(CGRect)frame {
  2452. self = [super initWithFrame:frame];
  2453. if (self) {
  2454. [self.contentView.layer addSublayer:self.lineLayer];
  2455. [self.contentView addSubview:self.textLb];
  2456. }
  2457. return self;
  2458. }
  2459. - (void)config {
  2460. self.backgroundColor = [HXPhotoCommon photoCommon].isDark ? self.bgDarkColor : self.bgColor;
  2461. self.lineLayer.strokeColor = [HXPhotoCommon photoCommon].isDark ? self.lineDarkColor.CGColor : self.lineColor.CGColor;
  2462. self.textLb.textColor = [HXPhotoCommon photoCommon].isDark ? self.textDarkColor : self.textColor;
  2463. self.textLb.font = self.textFont;
  2464. }
  2465. - (void)layoutSubviews {
  2466. [super layoutSubviews];
  2467. self.lineLayer.frame = self.bounds;
  2468. CGFloat centerX = self.hx_w * 0.5;
  2469. CGFloat centerY = (self.hx_h - 20) * 0.5;
  2470. CGFloat margin = 12.5;
  2471. self.textLb.hx_x = 0;
  2472. self.textLb.hx_y = centerY + 23;
  2473. self.textLb.hx_w = self.hx_w;
  2474. self.textLb.hx_h = [self.textLb hx_getTextHeight];
  2475. UIBezierPath *path = [UIBezierPath bezierPath];
  2476. [path moveToPoint:CGPointMake(centerX - margin, centerY)];
  2477. [path addLineToPoint:CGPointMake(centerX + margin, centerY)];
  2478. [path moveToPoint:CGPointMake(centerX, centerY - margin)];
  2479. [path addLineToPoint:CGPointMake(centerX, centerY + margin)];
  2480. self.lineLayer.path = path.CGPath;
  2481. }
  2482. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  2483. [super traitCollectionDidChange:previousTraitCollection];
  2484. #ifdef __IPHONE_13_0
  2485. if (@available(iOS 13.0, *)) {
  2486. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  2487. [self config];
  2488. }
  2489. }
  2490. #endif
  2491. }
  2492. @end
  2493. @interface HXPhotoViewCell ()
  2494. @property (strong, nonatomic) UIImageView *imageView;
  2495. @property (strong, nonatomic) UIView *maskView;
  2496. @property (copy, nonatomic) NSString *localIdentifier;
  2497. @property (assign, nonatomic) PHImageRequestID requestID;
  2498. @property (assign, nonatomic) PHImageRequestID iCloudRequestID;
  2499. @property (strong, nonatomic) UILabel *stateLb;
  2500. @property (strong, nonatomic) CAGradientLayer *bottomMaskLayer;
  2501. @property (strong, nonatomic) UIButton *selectBtn;
  2502. @property (strong, nonatomic) UIImageView *iCloudIcon;
  2503. @property (strong, nonatomic) CALayer *iCloudMaskLayer;
  2504. @property (strong, nonatomic) HXCircleProgressView *progressView;
  2505. @property (strong, nonatomic) CALayer *videoMaskLayer;
  2506. @property (strong, nonatomic) UIView *highlightMaskView;
  2507. @property (strong, nonatomic) UIImageView *editTipIcon;
  2508. @property (strong, nonatomic) UIImageView *videoIcon;
  2509. @property (assign, nonatomic) CGFloat seletBtnNormalWidth;
  2510. @end
  2511. @implementation HXPhotoViewCell
  2512. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  2513. [super traitCollectionDidChange:previousTraitCollection];
  2514. #ifdef __IPHONE_13_0
  2515. if (@available(iOS 13.0, *)) {
  2516. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  2517. self.selectMaskLayer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5].CGColor;
  2518. UIColor *cellSelectedTitleColor;
  2519. UIColor *cellSelectedBgColor;
  2520. if ([HXPhotoCommon photoCommon].isDark) {
  2521. cellSelectedTitleColor = self.darkSelectedTitleColor;
  2522. cellSelectedBgColor = self.darkSelectBgColor;
  2523. }else {
  2524. cellSelectedTitleColor = self.selectedTitleColor;
  2525. cellSelectedBgColor = self.selectBgColor;
  2526. }
  2527. if ([cellSelectedBgColor isEqual:[UIColor whiteColor]] && !cellSelectedTitleColor) {
  2528. [self.selectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
  2529. }else {
  2530. [self.selectBtn setTitleColor:cellSelectedTitleColor forState:UIControlStateSelected];
  2531. }
  2532. self.selectBtn.tintColor = cellSelectedBgColor;
  2533. }
  2534. }
  2535. #endif
  2536. }
  2537. - (void)willRemoveSubview:(UIView *)subview {
  2538. [super willRemoveSubview:subview];
  2539. [subview.layer removeAllAnimations];
  2540. }
  2541. - (instancetype)initWithFrame:(CGRect)frame {
  2542. self = [super initWithFrame:frame];
  2543. if (self) {
  2544. [self setupUI];
  2545. }
  2546. return self;
  2547. }
  2548. - (void)setupUI {
  2549. [self.contentView addSubview:self.imageView];
  2550. [self.contentView addSubview:self.maskView];
  2551. [self.contentView addSubview:self.highlightMaskView];
  2552. [self.contentView addSubview:self.progressView];
  2553. }
  2554. - (void)bottomViewPrepareAnimation {
  2555. [self.maskView.layer removeAllAnimations];
  2556. self.maskView.alpha = 0;
  2557. }
  2558. - (void)bottomViewStartAnimation {
  2559. [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  2560. self.maskView.alpha = 1;
  2561. } completion:nil];
  2562. }
  2563. - (void)setSingleSelected:(BOOL)singleSelected {
  2564. _singleSelected = singleSelected;
  2565. if (singleSelected) {
  2566. if (self.selectBtn.superview) {
  2567. [self.selectBtn removeFromSuperview];
  2568. }
  2569. }
  2570. }
  2571. - (void)resetNetworkImage {
  2572. if (self.model.networkPhotoUrl &&
  2573. self.model.type == HXPhotoModelMediaTypeCameraPhoto) {
  2574. self.model.loadOriginalImage = YES;
  2575. self.model.previewViewSize = CGSizeZero;
  2576. self.model.endImageSize = CGSizeZero;
  2577. HXWeakSelf
  2578. [self.imageView hx_setImageWithModel:self.model original:YES progress:nil completed:^(UIImage *image, NSError *error, HXPhotoModel *model) {
  2579. if (weakSelf.model == model) {
  2580. if (image.images.count) {
  2581. weakSelf.imageView.image = nil;
  2582. weakSelf.imageView.image = image.images.firstObject;
  2583. }else {
  2584. weakSelf.imageView.image = image;
  2585. }
  2586. }
  2587. }];
  2588. }
  2589. }
  2590. - (void)setModel:(HXPhotoModel *)model emptyImage:(BOOL)emptyImage {
  2591. _model = model;
  2592. if (emptyImage) {
  2593. self.imageView.image = nil;
  2594. }
  2595. self.maskView.hidden = YES;
  2596. }
  2597. - (void)setModelDataWithHighQuality:(BOOL)highQuality completion:(void (^)(HXPhotoViewCell *))completion {
  2598. HXPhotoModel *model = self.model;
  2599. self.videoIcon.hidden = YES;
  2600. self.editTipIcon.hidden = model.photoEdit ? NO : YES;
  2601. self.progressView.hidden = YES;
  2602. self.progressView.progress = 0;
  2603. self.maskView.hidden = !self.imageView.image;
  2604. self.localIdentifier = model.asset.localIdentifier;
  2605. if (model.photoEdit) {
  2606. self.imageView.image = model.photoEdit.editPreviewImage;
  2607. self.maskView.hidden = NO;
  2608. if (completion) {
  2609. completion(self);
  2610. }
  2611. self.requestID = 0;
  2612. }else {
  2613. HXWeakSelf
  2614. if (model.type == HXPhotoModelMediaTypeCamera ||
  2615. model.type == HXPhotoModelMediaTypeCameraPhoto ||
  2616. model.type == HXPhotoModelMediaTypeCameraVideo ||
  2617. model.type == HXPhotoModelMediaTypeLimit) {
  2618. if (model.thumbPhoto.images.count) {
  2619. self.imageView.image = nil;
  2620. self.imageView.image = model.thumbPhoto.images.firstObject;
  2621. }else {
  2622. self.imageView.image = model.thumbPhoto;
  2623. }
  2624. if (model.networkPhotoUrl) {
  2625. CGFloat progress = (CGFloat)model.receivedSize / model.expectedSize;
  2626. self.progressView.progress = progress;
  2627. if (model.downloadComplete && !model.downloadError) {
  2628. self.maskView.hidden = NO;
  2629. if (model.previewPhoto.images.count) {
  2630. self.imageView.image = nil;
  2631. self.imageView.image = model.previewPhoto.images.firstObject;
  2632. }else {
  2633. self.imageView.image = model.previewPhoto;
  2634. }
  2635. if (completion) {
  2636. completion(self);
  2637. }
  2638. }else {
  2639. self.progressView.hidden = NO;
  2640. [self.imageView hx_setImageWithModel:model original:NO progress:^(CGFloat progress, HXPhotoModel *model) {
  2641. if (weakSelf.model == model) {
  2642. weakSelf.progressView.progress = progress;
  2643. }
  2644. } completed:^(UIImage *image, NSError *error, HXPhotoModel *model) {
  2645. if (weakSelf.model == model) {
  2646. if (error != nil) {
  2647. [weakSelf.progressView showError];
  2648. }else {
  2649. if (image) {
  2650. weakSelf.maskView.hidden = NO;
  2651. if (image.images.count) {
  2652. weakSelf.imageView.image = nil;
  2653. weakSelf.imageView.image = image.images.firstObject;
  2654. }else {
  2655. weakSelf.imageView.image = image;
  2656. }
  2657. weakSelf.progressView.progress = 1;
  2658. weakSelf.progressView.hidden = YES;
  2659. }
  2660. }
  2661. }
  2662. if (completion) {
  2663. completion(weakSelf);
  2664. }
  2665. }];
  2666. }
  2667. }else {
  2668. self.maskView.hidden = NO;
  2669. if (completion) {
  2670. completion(self);
  2671. }
  2672. }
  2673. self.requestID = 0;
  2674. }else {
  2675. PHImageRequestID imageRequestID;
  2676. if (highQuality) {
  2677. imageRequestID = [self.model highQualityRequestThumbImageWithWidth:[HXPhotoCommon photoCommon].requestWidth completion:^(UIImage * _Nullable image, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) {
  2678. if ([[info objectForKey:PHImageCancelledKey] boolValue]) {
  2679. return;
  2680. }
  2681. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2682. if (weakSelf.maskView.hidden) {
  2683. weakSelf.maskView.hidden = NO;
  2684. }
  2685. weakSelf.imageView.image = image;
  2686. }
  2687. BOOL isDegraded = [[info objectForKey:PHImageResultIsDegradedKey] boolValue];
  2688. if (!isDegraded) {
  2689. weakSelf.requestID = 0;
  2690. }
  2691. if (completion) {
  2692. completion(weakSelf);
  2693. }
  2694. }];
  2695. }else {
  2696. imageRequestID = [weakSelf.model requestThumbImageCompletion:^(UIImage *image, HXPhotoModel *model, NSDictionary *info) {
  2697. if ([[info objectForKey:PHImageCancelledKey] boolValue]) {
  2698. return;
  2699. }
  2700. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2701. if (weakSelf.maskView.hidden) {
  2702. weakSelf.maskView.hidden = NO;
  2703. }
  2704. weakSelf.imageView.image = image;
  2705. }
  2706. BOOL isDegraded = [[info objectForKey:PHImageResultIsDegradedKey] boolValue];
  2707. if (!isDegraded) {
  2708. weakSelf.requestID = 0;
  2709. }
  2710. if (completion) {
  2711. completion(weakSelf);
  2712. }
  2713. }];
  2714. }
  2715. if (imageRequestID && self.requestID && imageRequestID != self.requestID) {
  2716. [[PHImageManager defaultManager] cancelImageRequest:self.requestID];
  2717. }
  2718. self.requestID = imageRequestID;
  2719. }
  2720. }
  2721. if (model.type == HXPhotoModelMediaTypePhotoGif && !model.photoEdit) {
  2722. self.stateLb.text = @"GIF";
  2723. self.stateLb.hidden = NO;
  2724. self.bottomMaskLayer.hidden = NO;
  2725. }else if (model.type == HXPhotoModelMediaTypeLivePhoto && !model.photoEdit) {
  2726. self.stateLb.text = @"Live";
  2727. self.stateLb.hidden = NO;
  2728. self.bottomMaskLayer.hidden = NO;
  2729. }else {
  2730. if (model.subType == HXPhotoModelMediaSubTypeVideo) {
  2731. self.stateLb.text = model.videoTime;
  2732. self.stateLb.hidden = NO;
  2733. self.videoIcon.hidden = NO;
  2734. self.bottomMaskLayer.hidden = NO;
  2735. }else {
  2736. if ((model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeNetWorkGif ||
  2737. model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeLocalGif) && !model.photoEdit) {
  2738. self.stateLb.text = @"GIF";
  2739. self.stateLb.hidden = NO;
  2740. self.bottomMaskLayer.hidden = NO;
  2741. }else if ((model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeLocalLivePhoto ||
  2742. model.cameraPhotoType == HXPhotoModelMediaTypeCameraPhotoTypeNetWorkLivePhoto) && !model.photoEdit) {
  2743. self.stateLb.text = @"Live";
  2744. self.stateLb.hidden = NO;
  2745. self.bottomMaskLayer.hidden = NO;
  2746. }else {
  2747. self.stateLb.hidden = YES;
  2748. if (model.photoEdit) {
  2749. self.bottomMaskLayer.hidden = NO;
  2750. }else {
  2751. self.bottomMaskLayer.hidden = YES;
  2752. }
  2753. }
  2754. }
  2755. }
  2756. self.selectMaskLayer.hidden = !model.selected;
  2757. self.selectBtn.selected = model.selected;
  2758. [self.selectBtn setTitle:model.selectIndexStr forState:UIControlStateSelected];
  2759. self.iCloudIcon.hidden = !model.isICloud;
  2760. self.iCloudMaskLayer.hidden = !model.isICloud;
  2761. // 当前是否需要隐藏选择按钮
  2762. if (model.needHideSelectBtn) {
  2763. self.selectBtn.hidden = YES;
  2764. self.selectBtn.userInteractionEnabled = NO;
  2765. }else {
  2766. self.selectBtn.hidden = model.isICloud;
  2767. self.selectBtn.userInteractionEnabled = !model.isICloud;
  2768. }
  2769. if (model.isICloud) {
  2770. self.videoMaskLayer.hidden = YES;
  2771. }else {
  2772. self.videoMaskLayer.hidden = self.canSelect;
  2773. }
  2774. if (model.iCloudDownloading) {
  2775. if (model.isICloud) {
  2776. self.progressView.hidden = NO;
  2777. self.highlightMaskView.hidden = NO;
  2778. self.progressView.progress = model.iCloudProgress;
  2779. [self startRequestICloudAsset];
  2780. }else {
  2781. model.iCloudDownloading = NO;
  2782. self.progressView.hidden = YES;
  2783. self.highlightMaskView.hidden = YES;
  2784. }
  2785. }else {
  2786. self.highlightMaskView.hidden = YES;
  2787. }
  2788. [self setSelectBtnFrame];
  2789. }
  2790. - (void)setSelectBgColor:(UIColor *)selectBgColor {
  2791. _selectBgColor = selectBgColor;
  2792. if ([HXPhotoCommon photoCommon].isDark) {
  2793. selectBgColor = self.darkSelectBgColor;
  2794. }
  2795. self.selectBtn.tintColor = selectBgColor;
  2796. if ([selectBgColor isEqual:[UIColor whiteColor]] && !self.selectedTitleColor) {
  2797. [self.selectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
  2798. }
  2799. }
  2800. - (void)setSelectedTitleColor:(UIColor *)selectedTitleColor {
  2801. _selectedTitleColor = selectedTitleColor;
  2802. if ([HXPhotoCommon photoCommon].isDark) {
  2803. selectedTitleColor = self.darkSelectedTitleColor;
  2804. }
  2805. [self.selectBtn setTitleColor:selectedTitleColor forState:UIControlStateSelected];
  2806. }
  2807. - (void)startRequestICloudAsset {
  2808. self.progressView.progress = 0;
  2809. self.iCloudIcon.hidden = YES;
  2810. self.iCloudMaskLayer.hidden = YES;
  2811. HXWeakSelf
  2812. if (self.model.type == HXPhotoModelMediaTypeVideo) {
  2813. self.iCloudRequestID = [self.model requestAVAssetStartRequestICloud:^(PHImageRequestID iCloudRequestId, HXPhotoModel *model) {
  2814. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2815. weakSelf.progressView.hidden = NO;
  2816. weakSelf.highlightMaskView.hidden = NO;
  2817. weakSelf.iCloudRequestID = iCloudRequestId;
  2818. }
  2819. } progressHandler:^(double progress, HXPhotoModel *model) {
  2820. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2821. weakSelf.progressView.hidden = NO;
  2822. weakSelf.highlightMaskView.hidden = NO;
  2823. weakSelf.progressView.progress = progress;
  2824. }
  2825. } success:^(AVAsset *avAsset, AVAudioMix *audioMix, HXPhotoModel *model, NSDictionary *info) {
  2826. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2827. weakSelf.model.isICloud = NO;
  2828. weakSelf.progressView.progress = 1;
  2829. weakSelf.highlightMaskView.hidden = YES;
  2830. weakSelf.iCloudRequestID = 0;
  2831. if ([weakSelf.delegate respondsToSelector:@selector(photoViewCellRequestICloudAssetComplete:)]) {
  2832. [weakSelf.delegate photoViewCellRequestICloudAssetComplete:weakSelf];
  2833. }
  2834. }
  2835. } failed:^(NSDictionary *info, HXPhotoModel *model) {
  2836. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2837. [weakSelf downloadError:info];
  2838. }
  2839. }];
  2840. }else if (self.model.type == HXPhotoModelMediaTypeLivePhoto){
  2841. self.iCloudRequestID = [self.model requestLivePhotoWithSize:CGSizeMake(self.model.previewViewSize.width * 1.5, self.model.previewViewSize.height * 1.5) startRequestICloud:^(PHImageRequestID iCloudRequestId, HXPhotoModel *model) {
  2842. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2843. weakSelf.progressView.hidden = NO;
  2844. weakSelf.highlightMaskView.hidden = NO;
  2845. weakSelf.iCloudRequestID = iCloudRequestId;
  2846. }
  2847. } progressHandler:^(double progress, HXPhotoModel *model) {
  2848. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2849. weakSelf.progressView.hidden = NO;
  2850. weakSelf.highlightMaskView.hidden = NO;
  2851. weakSelf.progressView.progress = progress;
  2852. }
  2853. } success:^(PHLivePhoto *livePhoto, HXPhotoModel *model, NSDictionary *info) {
  2854. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2855. weakSelf.model.isICloud = NO;
  2856. weakSelf.progressView.progress = 1;
  2857. weakSelf.highlightMaskView.hidden = YES;
  2858. weakSelf.iCloudRequestID = 0;
  2859. if ([weakSelf.delegate respondsToSelector:@selector(photoViewCellRequestICloudAssetComplete:)]) {
  2860. [weakSelf.delegate photoViewCellRequestICloudAssetComplete:weakSelf];
  2861. }
  2862. }
  2863. } failed:^(NSDictionary *info, HXPhotoModel *model) {
  2864. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2865. [weakSelf downloadError:info];
  2866. }
  2867. }];
  2868. }else {
  2869. self.iCloudRequestID = [self.model requestImageDataStartRequestICloud:^(PHImageRequestID iCloudRequestId, HXPhotoModel *model) {
  2870. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2871. weakSelf.progressView.hidden = NO;
  2872. weakSelf.highlightMaskView.hidden = NO;
  2873. weakSelf.iCloudRequestID = iCloudRequestId;
  2874. }
  2875. } progressHandler:^(double progress, HXPhotoModel *model) {
  2876. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2877. weakSelf.progressView.hidden = NO;
  2878. weakSelf.highlightMaskView.hidden = NO;
  2879. weakSelf.progressView.progress = progress;
  2880. }
  2881. } success:^(NSData *imageData, UIImageOrientation orientation, HXPhotoModel *model, NSDictionary *info) {
  2882. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2883. weakSelf.model.isICloud = NO;
  2884. weakSelf.highlightMaskView.hidden = YES;
  2885. weakSelf.progressView.progress = 1;
  2886. weakSelf.iCloudRequestID = 0;
  2887. if ([weakSelf.delegate respondsToSelector:@selector(photoViewCellRequestICloudAssetComplete:)]) {
  2888. [weakSelf.delegate photoViewCellRequestICloudAssetComplete:weakSelf];
  2889. }
  2890. }
  2891. } failed:^(NSDictionary *info, HXPhotoModel *model) {
  2892. if ([weakSelf.localIdentifier isEqualToString:model.asset.localIdentifier]) {
  2893. [weakSelf downloadError:info];
  2894. }
  2895. }];
  2896. }
  2897. }
  2898. - (void)downloadError:(NSDictionary *)info {
  2899. if (![[info objectForKey:PHImageCancelledKey] boolValue]) {
  2900. [[self hx_viewController].view hx_showImageHUDText:[NSBundle hx_localizedStringForKey:@"下载失败,请重试!"]];
  2901. }
  2902. self.highlightMaskView.hidden = YES;
  2903. self.progressView.hidden = YES;
  2904. self.progressView.progress = 0;
  2905. self.iCloudIcon.hidden = !self.model.isICloud;
  2906. self.iCloudMaskLayer.hidden = !self.model.isICloud;
  2907. }
  2908. - (void)cancelRequest {
  2909. if (self.requestID) {
  2910. [[PHImageManager defaultManager] cancelImageRequest:self.requestID];
  2911. self.requestID = 0;
  2912. }
  2913. if (self.iCloudRequestID) {
  2914. [[PHImageManager defaultManager] cancelImageRequest:self.iCloudRequestID];
  2915. self.iCloudRequestID = 0;
  2916. }
  2917. }
  2918. - (void)didSelectClick:(UIButton *)button {
  2919. if (self.model.type == HXPhotoModelMediaTypeCamera ||
  2920. self.model.type == HXPhotoModelMediaTypeLimit) {
  2921. return;
  2922. }
  2923. if (self.model.isICloud) {
  2924. return;
  2925. }
  2926. if ([self.delegate respondsToSelector:@selector(photoViewCell:didSelectBtn:)]) {
  2927. [self.delegate photoViewCell:self didSelectBtn:button];
  2928. }
  2929. [self setSelectBtnFrame];
  2930. }
  2931. - (void)setHighlighted:(BOOL)highlighted {
  2932. [super setHighlighted:highlighted];
  2933. self.highlightMaskView.hidden = !highlighted;
  2934. }
  2935. - (void)layoutSubviews {
  2936. [super layoutSubviews];
  2937. self.imageView.frame = self.bounds;
  2938. self.maskView.frame = self.bounds;
  2939. self.stateLb.frame = CGRectMake(0, self.hx_h - 18, self.hx_w - 7, 18);
  2940. self.bottomMaskLayer.frame = CGRectMake(0, self.hx_h - 25, self.hx_w, 27);
  2941. [self setSelectBtnFrame];
  2942. self.selectMaskLayer.frame = self.bounds;
  2943. self.iCloudMaskLayer.frame = self.bounds;
  2944. self.iCloudIcon.hx_x = self.hx_w - 3 - self.iCloudIcon.hx_w;
  2945. self.iCloudIcon.hx_y = 3;
  2946. self.progressView.center = CGPointMake(self.hx_w / 2, self.hx_h / 2);
  2947. self.videoMaskLayer.frame = self.bounds;
  2948. self.highlightMaskView.frame = self.bounds;
  2949. self.editTipIcon.hx_x = 7;
  2950. self.editTipIcon.hx_y = self.hx_h - 4 - self.editTipIcon.hx_h;
  2951. self.videoIcon.hx_x = 7;
  2952. self.videoIcon.hx_y = self.hx_h - 4 - self.videoIcon.hx_h;
  2953. self.stateLb.hx_centerY = self.videoIcon.hx_centerY;
  2954. }
  2955. - (void)setSelectBtnFrame {
  2956. CGFloat textWidth = [self.selectBtn.titleLabel hx_getTextWidth];
  2957. if (textWidth + 10 > self.seletBtnNormalWidth && self.selectBtn.selected) {
  2958. self.selectBtn.hx_w = textWidth + 10;
  2959. }else {
  2960. self.selectBtn.hx_w = self.seletBtnNormalWidth;
  2961. }
  2962. self.selectBtn.hx_x = self.hx_w - self.selectBtn.hx_w - 5;
  2963. self.selectBtn.hx_y = 5;
  2964. }
  2965. - (void)dealloc {
  2966. self.delegate = nil;
  2967. self.model.dateCellIsVisible = NO;
  2968. }
  2969. #pragma mark - < 懒加载 >
  2970. - (UIView *)highlightMaskView {
  2971. if (!_highlightMaskView) {
  2972. _highlightMaskView = [[UIView alloc] initWithFrame:self.bounds];
  2973. _highlightMaskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
  2974. _highlightMaskView.hidden = YES;
  2975. }
  2976. return _highlightMaskView;
  2977. }
  2978. - (HXCircleProgressView *)progressView {
  2979. if (!_progressView) {
  2980. _progressView = [[HXCircleProgressView alloc] init];
  2981. _progressView.hidden = YES;
  2982. }
  2983. return _progressView;
  2984. }
  2985. - (UIImageView *)editTipIcon {
  2986. if (!_editTipIcon) {
  2987. _editTipIcon = [[UIImageView alloc] initWithImage:[UIImage hx_imageNamed:@"hx_photo_edit_show_tip"]];
  2988. _editTipIcon.hx_size = _editTipIcon.image.size;
  2989. }
  2990. return _editTipIcon;
  2991. }
  2992. - (UIImageView *)videoIcon {
  2993. if (!_videoIcon) {
  2994. _videoIcon = [[UIImageView alloc] initWithImage:[UIImage hx_imageNamed:@"hx_photo_asset_video_icon"]];
  2995. _videoIcon.hx_size = _videoIcon.image.size;
  2996. }
  2997. return _videoIcon;
  2998. }
  2999. - (UIImageView *)imageView {
  3000. if (!_imageView) {
  3001. _imageView = [[UIImageView alloc] init];
  3002. _imageView.contentMode = UIViewContentModeScaleAspectFill;
  3003. _imageView.clipsToBounds = YES;
  3004. }
  3005. return _imageView;
  3006. }
  3007. - (UIView *)maskView {
  3008. if (!_maskView) {
  3009. _maskView = [[UIView alloc] init];
  3010. [_maskView.layer addSublayer:self.bottomMaskLayer];
  3011. [_maskView.layer addSublayer:self.selectMaskLayer];
  3012. [_maskView.layer addSublayer:self.iCloudMaskLayer];
  3013. [_maskView addSubview:self.iCloudIcon];
  3014. [_maskView addSubview:self.selectBtn];
  3015. [_maskView.layer addSublayer:self.videoMaskLayer];
  3016. [_maskView addSubview:self.stateLb];
  3017. [_maskView addSubview:self.editTipIcon];
  3018. [_maskView addSubview:self.videoIcon];
  3019. }
  3020. return _maskView;
  3021. }
  3022. - (UIImageView *)iCloudIcon {
  3023. if (!_iCloudIcon) {
  3024. _iCloudIcon = [[UIImageView alloc] initWithImage:[UIImage hx_imageNamed:@"hx_yunxiazai"]];
  3025. _iCloudIcon.hx_size = _iCloudIcon.image.size;
  3026. }
  3027. return _iCloudIcon;
  3028. }
  3029. - (CALayer *)selectMaskLayer {
  3030. if (!_selectMaskLayer) {
  3031. _selectMaskLayer = [CALayer layer];
  3032. _selectMaskLayer.hidden = YES;
  3033. _selectMaskLayer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5].CGColor;
  3034. }
  3035. return _selectMaskLayer;
  3036. }
  3037. - (CALayer *)iCloudMaskLayer {
  3038. if (!_iCloudMaskLayer) {
  3039. _iCloudMaskLayer = [CALayer layer];
  3040. _iCloudMaskLayer.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3].CGColor;
  3041. }
  3042. return _iCloudMaskLayer;
  3043. }
  3044. - (CALayer *)videoMaskLayer {
  3045. if (!_videoMaskLayer) {
  3046. _videoMaskLayer = [CALayer layer];
  3047. _videoMaskLayer.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
  3048. }
  3049. return _videoMaskLayer;
  3050. }
  3051. - (UILabel *)stateLb {
  3052. if (!_stateLb) {
  3053. _stateLb = [[UILabel alloc] init];
  3054. _stateLb.textColor = [UIColor whiteColor];
  3055. _stateLb.textAlignment = NSTextAlignmentRight;
  3056. _stateLb.font = [UIFont hx_mediumSFUITextOfSize:13];
  3057. }
  3058. return _stateLb;
  3059. }
  3060. - (CAGradientLayer *)bottomMaskLayer {
  3061. if (!_bottomMaskLayer) {
  3062. _bottomMaskLayer = [CAGradientLayer layer];
  3063. _bottomMaskLayer.colors = @[
  3064. (id)[[UIColor blackColor] colorWithAlphaComponent:0].CGColor ,
  3065. (id)[[UIColor blackColor] colorWithAlphaComponent:0.15].CGColor ,
  3066. (id)[[UIColor blackColor] colorWithAlphaComponent:0.35].CGColor ,
  3067. (id)[[UIColor blackColor] colorWithAlphaComponent:0.6].CGColor
  3068. ];
  3069. _bottomMaskLayer.startPoint = CGPointMake(0, 0);
  3070. _bottomMaskLayer.endPoint = CGPointMake(0, 1);
  3071. _bottomMaskLayer.locations = @[@(0.15f),@(0.35f),@(0.6f),@(0.9f)];
  3072. _bottomMaskLayer.borderWidth = 0.0;
  3073. }
  3074. return _bottomMaskLayer;
  3075. }
  3076. - (UIButton *)selectBtn {
  3077. if (!_selectBtn) {
  3078. _selectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  3079. [_selectBtn setBackgroundImage:[UIImage hx_imageNamed:@"hx_compose_guide_check_box_default"] forState:UIControlStateNormal];
  3080. UIImage *bgImage = [[UIImage hx_imageNamed:@"hx_compose_guide_check_box_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
  3081. bgImage = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(bgImage.size.width / 2, bgImage.size.width / 2, bgImage.size.width / 2, bgImage.size.width / 2) resizingMode:UIImageResizingModeStretch];
  3082. [_selectBtn setBackgroundImage:bgImage forState:UIControlStateSelected];
  3083. [_selectBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
  3084. _selectBtn.titleLabel.font = [UIFont hx_mediumPingFangOfSize:16];
  3085. _selectBtn.hx_size = _selectBtn.currentBackgroundImage.size;
  3086. self.seletBtnNormalWidth = _selectBtn.hx_w;
  3087. [_selectBtn addTarget:self action:@selector(didSelectClick:) forControlEvents:UIControlEventTouchUpInside];
  3088. [_selectBtn hx_setEnlargeEdgeWithTop:0 right:0 bottom:15 left:15];
  3089. }
  3090. return _selectBtn;
  3091. }
  3092. @end
  3093. @interface HXPhotoViewSectionFooterView ()
  3094. @property (strong, nonatomic) UILabel *titleLb;
  3095. @end
  3096. @implementation HXPhotoViewSectionFooterView
  3097. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  3098. [super traitCollectionDidChange:previousTraitCollection];
  3099. #ifdef __IPHONE_13_0
  3100. if (@available(iOS 13.0, *)) {
  3101. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  3102. if ([HXPhotoCommon photoCommon].isDark) {
  3103. self.backgroundColor = [UIColor colorWithRed:0.075 green:0.075 blue:0.075 alpha:1];
  3104. }else {
  3105. self.backgroundColor = self.bgColor;
  3106. }
  3107. [self setVideoCount:self.videoCount];
  3108. }
  3109. }
  3110. #endif
  3111. }
  3112. - (instancetype)initWithFrame:(CGRect)frame {
  3113. self = [super initWithFrame:frame];
  3114. if (self) {
  3115. [self setupUI];
  3116. }
  3117. return self;
  3118. }
  3119. - (void)setupUI {
  3120. if ([HXPhotoCommon photoCommon].isDark) {
  3121. self.backgroundColor = [UIColor colorWithRed:0.075 green:0.075 blue:0.075 alpha:1];
  3122. }else {
  3123. self.backgroundColor = self.bgColor;
  3124. }
  3125. [self addSubview:self.titleLb];
  3126. }
  3127. - (void)setVideoCount:(NSInteger)videoCount {
  3128. _videoCount = videoCount;
  3129. UIColor *textColor = [HXPhotoCommon photoCommon].isDark ? [UIColor whiteColor] : self.textColor;
  3130. NSDictionary *dict = @{NSFontAttributeName : [UIFont hx_mediumSFUITextOfSize:15] ,
  3131. NSForegroundColorAttributeName : textColor
  3132. };
  3133. NSAttributedString *photoCountStr = [[NSAttributedString alloc] initWithString:[@(self.photoCount).stringValue hx_countStrBecomeComma] attributes:dict];
  3134. NSAttributedString *videoCountStr = [[NSAttributedString alloc] initWithString:[@(videoCount).stringValue hx_countStrBecomeComma] attributes:dict];
  3135. if (self.photoCount > 0 && videoCount > 0) {
  3136. NSString *photoStr;
  3137. if (self.photoCount > 1) {
  3138. photoStr = @"Photos";
  3139. }else {
  3140. photoStr = @"Photo";
  3141. }
  3142. NSString *videoStr;
  3143. if (videoCount > 1) {
  3144. videoStr = @"Videos";
  3145. }else {
  3146. videoStr = @"Video";
  3147. }
  3148. NSMutableAttributedString *atbStr = [[NSMutableAttributedString alloc] init];
  3149. NSAttributedString *photoAtbStr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@、",[NSBundle hx_localizedStringForKey:photoStr]] attributes:dict];
  3150. [atbStr appendAttributedString:photoCountStr];
  3151. [atbStr appendAttributedString:photoAtbStr];
  3152. NSAttributedString *videoAtbStr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@",[NSBundle hx_localizedStringForKey:videoStr]] attributes:dict];
  3153. [atbStr appendAttributedString:videoCountStr];
  3154. [atbStr appendAttributedString:videoAtbStr];
  3155. self.titleLb.attributedText = atbStr;
  3156. }else if (self.photoCount > 0) {
  3157. NSString *photoStr;
  3158. if (self.photoCount > 1) {
  3159. photoStr = @"Photos";
  3160. }else {
  3161. photoStr = @"Photo";
  3162. }
  3163. NSMutableAttributedString *atbStr = [[NSMutableAttributedString alloc] init];
  3164. NSAttributedString *photoAtbStr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@",[NSBundle hx_localizedStringForKey:photoStr]] attributes:dict];
  3165. [atbStr appendAttributedString:photoCountStr];
  3166. [atbStr appendAttributedString:photoAtbStr];
  3167. self.titleLb.attributedText = atbStr;
  3168. }else {
  3169. NSString *videoStr;
  3170. if (videoCount > 1) {
  3171. videoStr = @"Videos";
  3172. }else {
  3173. videoStr = @"Video";
  3174. }
  3175. NSMutableAttributedString *atbStr = [[NSMutableAttributedString alloc] init];
  3176. NSAttributedString *videoAtbStr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@",[NSBundle hx_localizedStringForKey:videoStr]] attributes:dict];
  3177. [atbStr appendAttributedString:videoCountStr];
  3178. [atbStr appendAttributedString:videoAtbStr];
  3179. self.titleLb.attributedText = atbStr;
  3180. }
  3181. }
  3182. - (void)layoutSubviews {
  3183. [super layoutSubviews];
  3184. self.titleLb.frame = CGRectMake(0, 0, self.hx_w, 50);
  3185. }
  3186. - (UILabel *)titleLb {
  3187. if (!_titleLb) {
  3188. _titleLb = [[UILabel alloc] init];
  3189. _titleLb.textAlignment = NSTextAlignmentCenter;
  3190. }
  3191. return _titleLb;
  3192. }
  3193. @end
  3194. @interface HXPhotoBottomView ()
  3195. @property (strong, nonatomic) UIButton *previewBtn;
  3196. @property (strong, nonatomic) UIButton *doneBtn;
  3197. @property (strong, nonatomic) UIButton *editBtn;
  3198. @property (strong, nonatomic) UIActivityIndicatorView *loadingView;
  3199. @property (strong, nonatomic) UIColor *barTintColor;
  3200. @end
  3201. @implementation HXPhotoBottomView
  3202. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  3203. [super traitCollectionDidChange:previousTraitCollection];
  3204. #ifdef __IPHONE_13_0
  3205. if (@available(iOS 13.0, *)) {
  3206. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  3207. [self setManager:self.manager];
  3208. [self setSelectCount:self.selectCount];
  3209. }
  3210. }
  3211. #endif
  3212. }
  3213. - (instancetype)initWithFrame:(CGRect)frame {
  3214. self = [super initWithFrame:frame];
  3215. if (self) {
  3216. [self setupUI];
  3217. }
  3218. return self;
  3219. }
  3220. - (void)setupUI {
  3221. [self addSubview:self.bgView];
  3222. [self addSubview:self.previewBtn];
  3223. [self addSubview:self.originalBtn];
  3224. [self addSubview:self.doneBtn];
  3225. [self addSubview:self.editBtn];
  3226. [self changeDoneBtnFrame];
  3227. }
  3228. - (void)setManager:(HXPhotoManager *)manager {
  3229. _manager = manager;
  3230. self.bgView.translucent = manager.configuration.bottomViewTranslucent;
  3231. self.barTintColor = manager.configuration.bottomViewBgColor;
  3232. self.bgView.barStyle = manager.configuration.bottomViewBarStyle;
  3233. self.originalBtn.hidden = self.manager.configuration.hideOriginalBtn;
  3234. if (manager.type == HXPhotoManagerSelectedTypePhoto) {
  3235. self.editBtn.hidden = !manager.configuration.photoCanEdit;
  3236. }else if (manager.type == HXPhotoManagerSelectedTypeVideo) {
  3237. self.editBtn.hidden = !manager.configuration.videoCanEdit;
  3238. }else {
  3239. if (!manager.configuration.videoCanEdit && !manager.configuration.photoCanEdit) {
  3240. self.editBtn.hidden = YES;
  3241. }
  3242. }
  3243. self.originalBtn.selected = self.manager.original;
  3244. UIColor *themeColor;
  3245. UIColor *selectedTitleColor;
  3246. UIColor *originalBtnImageTintColor;
  3247. if ([HXPhotoCommon photoCommon].isDark) {
  3248. themeColor = [UIColor whiteColor];
  3249. originalBtnImageTintColor = themeColor;
  3250. selectedTitleColor = [UIColor whiteColor];
  3251. self.bgView.barTintColor = [UIColor blackColor];
  3252. }else {
  3253. self.bgView.barTintColor = self.barTintColor;
  3254. themeColor = self.manager.configuration.themeColor;
  3255. if (self.manager.configuration.originalBtnImageTintColor) {
  3256. originalBtnImageTintColor = self.manager.configuration.originalBtnImageTintColor;
  3257. }else {
  3258. originalBtnImageTintColor = themeColor;
  3259. }
  3260. if (self.manager.configuration.bottomDoneBtnTitleColor) {
  3261. selectedTitleColor = self.manager.configuration.bottomDoneBtnTitleColor;
  3262. }else {
  3263. selectedTitleColor = self.manager.configuration.selectedTitleColor;
  3264. }
  3265. }
  3266. [self.previewBtn setTitleColor:themeColor forState:UIControlStateNormal];
  3267. [self.previewBtn setTitleColor:[themeColor colorWithAlphaComponent:0.5] forState:UIControlStateDisabled];
  3268. [self.originalBtn setTitleColor:themeColor forState:UIControlStateNormal];
  3269. [self.originalBtn setTitleColor:[themeColor colorWithAlphaComponent:0.5] forState:UIControlStateDisabled];
  3270. UIImageRenderingMode rederingMode = self.manager.configuration.changeOriginalTinColor ? UIImageRenderingModeAlwaysTemplate : UIImageRenderingModeAlwaysOriginal;
  3271. UIImage *originalNormalImage = [[UIImage hx_imageNamed:self.manager.configuration.originalNormalImageName] imageWithRenderingMode:rederingMode];
  3272. UIImage *originalSelectedImage = [[UIImage hx_imageNamed:self.manager.configuration.originalSelectedImageName] imageWithRenderingMode:rederingMode];
  3273. [self.originalBtn setImage:originalNormalImage forState:UIControlStateNormal];
  3274. [self.originalBtn setImage:originalSelectedImage forState:UIControlStateSelected];
  3275. self.originalBtn.imageView.tintColor = originalBtnImageTintColor;
  3276. [self.editBtn setTitleColor:themeColor forState:UIControlStateNormal];
  3277. [self.editBtn setTitleColor:[themeColor colorWithAlphaComponent:0.5] forState:UIControlStateDisabled];
  3278. if ([themeColor isEqual:[UIColor whiteColor]]) {
  3279. [self.doneBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  3280. [self.doneBtn setTitleColor:[[UIColor blackColor] colorWithAlphaComponent:0.3] forState:UIControlStateDisabled];
  3281. }
  3282. if (selectedTitleColor) {
  3283. [self.doneBtn setTitleColor:selectedTitleColor forState:UIControlStateNormal];
  3284. [self.doneBtn setTitleColor:[selectedTitleColor colorWithAlphaComponent:0.3] forState:UIControlStateDisabled];
  3285. }
  3286. if (self.manager.configuration.showOriginalBytesLoading) {
  3287. self.loadingView.color = themeColor;
  3288. }
  3289. }
  3290. - (void)setSelectCount:(NSInteger)selectCount {
  3291. _selectCount = selectCount;
  3292. if (selectCount <= 0) {
  3293. self.previewBtn.enabled = NO;
  3294. self.doneBtn.enabled = NO;
  3295. [self.doneBtn setTitle:[NSBundle hx_localizedStringForKey:@"完成"] forState:UIControlStateNormal];
  3296. }else {
  3297. self.previewBtn.enabled = YES;
  3298. self.doneBtn.enabled = YES;
  3299. if (self.manager.configuration.doneBtnShowDetail) {
  3300. if (!self.manager.configuration.selectTogether) {
  3301. if (self.manager.selectedPhotoCount > 0) {
  3302. NSInteger maxCount = self.manager.configuration.photoMaxNum > 0 ? self.manager.configuration.photoMaxNum : self.manager.configuration.maxNum;
  3303. [self.doneBtn setTitle:[NSString stringWithFormat:@"%@(%ld/%ld)",[NSBundle hx_localizedStringForKey:@"完成"],(long)selectCount,(long)maxCount] forState:UIControlStateNormal];
  3304. }else {
  3305. NSInteger maxCount = self.manager.configuration.videoMaxNum > 0 ? self.manager.configuration.videoMaxNum : self.manager.configuration.maxNum;
  3306. [self.doneBtn setTitle:[NSString stringWithFormat:@"%@(%ld/%ld)",[NSBundle hx_localizedStringForKey:@"完成"],(long)selectCount,(long)maxCount] forState:UIControlStateNormal];
  3307. }
  3308. }else {
  3309. [self.doneBtn setTitle:[NSString stringWithFormat:@"%@(%ld/%lu)",[NSBundle hx_localizedStringForKey:@"完成"],(long)selectCount,(unsigned long)self.manager.configuration.maxNum] forState:UIControlStateNormal];
  3310. }
  3311. }else {
  3312. [self.doneBtn setTitle:[NSString stringWithFormat:@"%@(%ld)",[NSBundle hx_localizedStringForKey:@"完成"],(long)selectCount] forState:UIControlStateNormal];
  3313. }
  3314. }
  3315. UIColor *themeColor = self.manager.configuration.bottomDoneBtnBgColor ?: self.manager.configuration.themeColor;
  3316. UIColor *doneBtnDarkBgColor = self.manager.configuration.bottomDoneBtnDarkBgColor ?: [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
  3317. UIColor *doneBtnBgColor = [HXPhotoCommon photoCommon].isDark ? doneBtnDarkBgColor : themeColor;
  3318. UIColor *doneBtnEnabledBgColor = self.manager.configuration.bottomDoneBtnEnabledBgColor ?: [doneBtnBgColor colorWithAlphaComponent:0.5];
  3319. self.doneBtn.backgroundColor = self.doneBtn.enabled ? doneBtnBgColor : doneBtnEnabledBgColor;
  3320. if (!self.manager.configuration.selectTogether) {
  3321. if (self.manager.selectedPhotoArray.count) {
  3322. self.editBtn.enabled = self.manager.configuration.photoCanEdit;
  3323. }else if (self.manager.selectedVideoArray.count) {
  3324. self.editBtn.enabled = self.manager.configuration.videoCanEdit;
  3325. }else {
  3326. self.editBtn.enabled = NO;
  3327. }
  3328. }else {
  3329. if (self.manager.selectedArray.count) {
  3330. HXPhotoModel *model = self.manager.selectedArray.firstObject;
  3331. if (model.subType == HXPhotoModelMediaSubTypePhoto) {
  3332. self.editBtn.enabled = self.manager.configuration.photoCanEdit;
  3333. }else {
  3334. self.editBtn.enabled = self.manager.configuration.videoCanEdit;
  3335. }
  3336. }else {
  3337. self.editBtn.enabled = NO;
  3338. }
  3339. }
  3340. [self changeDoneBtnFrame];
  3341. [self requestPhotosBytes];
  3342. }
  3343. - (void)requestPhotosBytes {
  3344. if (!self.manager.configuration.showOriginalBytes) {
  3345. return;
  3346. }
  3347. if (self.originalBtn.selected) {
  3348. if (self.manager.configuration.showOriginalBytesLoading) {
  3349. [self resetOriginalBtn];
  3350. [self updateLoadingViewWithHidden:NO];
  3351. }
  3352. HXWeakSelf
  3353. [self.manager requestPhotosBytesWithCompletion:^(NSString *totalBytes, NSUInteger totalDataLengths) {
  3354. if (weakSelf.manager.configuration.showOriginalBytesLoading) {
  3355. [weakSelf updateLoadingViewWithHidden:YES];
  3356. }
  3357. if (totalDataLengths > 0) {
  3358. [weakSelf.originalBtn setTitle:[NSString stringWithFormat:@"%@(%@)",[NSBundle hx_localizedStringForKey:@"原图"], totalBytes] forState:UIControlStateNormal];
  3359. }else {
  3360. [weakSelf.originalBtn setTitle:[NSBundle hx_localizedStringForKey:@"原图"] forState:UIControlStateNormal];
  3361. }
  3362. [weakSelf updateOriginalBtnFrame];
  3363. }];
  3364. }else {
  3365. if (self.manager.configuration.showOriginalBytesLoading) {
  3366. [self updateLoadingViewWithHidden:YES];
  3367. }
  3368. [self resetOriginalBtn];
  3369. }
  3370. }
  3371. - (void)resetOriginalBtn {
  3372. [self.manager.dataOperationQueue cancelAllOperations];
  3373. [self.originalBtn setTitle:[NSBundle hx_localizedStringForKey:@"原图"] forState:UIControlStateNormal];
  3374. [self updateOriginalBtnFrame];
  3375. }
  3376. - (void)changeDoneBtnFrame {
  3377. CGFloat width = self.doneBtn.titleLabel.hx_getTextWidth;
  3378. self.doneBtn.hx_w = width + 20;
  3379. if (self.doneBtn.hx_w < 60) {
  3380. self.doneBtn.hx_w = 60;
  3381. }
  3382. self.doneBtn.hx_x = self.hx_w - 12 - self.doneBtn.hx_w;
  3383. }
  3384. - (void)updateOriginalBtnFrame {
  3385. if (self.editBtn.hidden) {
  3386. self.originalBtn.frame = CGRectMake(CGRectGetMaxX(self.previewBtn.frame) + 10, 0, 30, 50);
  3387. }else {
  3388. self.originalBtn.frame = CGRectMake(CGRectGetMaxX(self.editBtn.frame) + 10, 0, 30, 50);
  3389. }
  3390. self.originalBtn.hx_w = self.originalBtn.titleLabel.hx_getTextWidth + 30;
  3391. if (CGRectGetMaxX(self.originalBtn.frame) > self.doneBtn.hx_x - 25) {
  3392. CGFloat w = self.doneBtn.hx_x - 5 - self.originalBtn.hx_x;
  3393. self.originalBtn.hx_w = w < 0 ? 30 : w;
  3394. }
  3395. self.originalBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 5 , 0, 0);
  3396. }
  3397. - (void)updateLoadingViewWithHidden:(BOOL)hidden {
  3398. if (hidden && self.loadingView.hidden) {
  3399. return;
  3400. }
  3401. if (!hidden && !self.loadingView.hidden) {
  3402. return;
  3403. }
  3404. self.loadingView.hx_x = CGRectGetMaxX(self.originalBtn.frame) - 5;
  3405. self.loadingView.hx_centerY = self.originalBtn.hx_h / 2;
  3406. if (hidden) {
  3407. [self.loadingView stopAnimating];
  3408. }else {
  3409. [self.loadingView startAnimating];
  3410. }
  3411. self.loadingView.hidden = hidden;
  3412. }
  3413. - (void)didDoneBtnClick {
  3414. if ([self.delegate respondsToSelector:@selector(photoBottomViewDidDoneBtn)]) {
  3415. [self.delegate photoBottomViewDidDoneBtn];
  3416. }
  3417. }
  3418. - (void)didPreviewClick {
  3419. if ([self.delegate respondsToSelector:@selector(photoBottomViewDidPreviewBtn)]) {
  3420. [self.delegate photoBottomViewDidPreviewBtn];
  3421. }
  3422. }
  3423. - (void)didEditBtnClick {
  3424. if ([self.delegate respondsToSelector:@selector(photoBottomViewDidEditBtn)]) {
  3425. [self.delegate photoBottomViewDidEditBtn];
  3426. }
  3427. }
  3428. - (void)didOriginalClick:(UIButton *)button {
  3429. button.selected = !button.selected;
  3430. [self requestPhotosBytes];
  3431. [self.manager setOriginal:button.selected];
  3432. }
  3433. - (void)layoutSubviews {
  3434. [super layoutSubviews];
  3435. self.bgView.frame = self.bounds;
  3436. self.previewBtn.frame = CGRectMake(12, 0, 0, 50);
  3437. self.previewBtn.hx_w = self.previewBtn.titleLabel.hx_getTextWidth;
  3438. self.previewBtn.center = CGPointMake(self.previewBtn.center.x, 25);
  3439. self.editBtn.frame = CGRectMake(CGRectGetMaxX(self.previewBtn.frame) + 10, 0, 0, 50);
  3440. self.editBtn.hx_w = self.editBtn.titleLabel.hx_getTextWidth;
  3441. self.doneBtn.frame = CGRectMake(0, 0, 60, 30);
  3442. self.doneBtn.center = CGPointMake(self.doneBtn.center.x, 25);
  3443. [self changeDoneBtnFrame];
  3444. [self updateOriginalBtnFrame];
  3445. }
  3446. - (UIToolbar *)bgView {
  3447. if (!_bgView) {
  3448. _bgView = [[UIToolbar alloc] init];
  3449. }
  3450. return _bgView;
  3451. }
  3452. - (UIButton *)previewBtn {
  3453. if (!_previewBtn) {
  3454. _previewBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  3455. [_previewBtn setTitle:[NSBundle hx_localizedStringForKey:@"预览"] forState:UIControlStateNormal];
  3456. _previewBtn.titleLabel.font = [UIFont systemFontOfSize:16];
  3457. _previewBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  3458. [_previewBtn addTarget:self action:@selector(didPreviewClick) forControlEvents:UIControlEventTouchUpInside];
  3459. _previewBtn.enabled = NO;
  3460. }
  3461. return _previewBtn;
  3462. }
  3463. - (UIButton *)doneBtn {
  3464. if (!_doneBtn) {
  3465. _doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  3466. [_doneBtn setTitle:[NSBundle hx_localizedStringForKey:@"完成"] forState:UIControlStateNormal];
  3467. _doneBtn.titleLabel.font = [UIFont hx_mediumPingFangOfSize:16];
  3468. [_doneBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  3469. [_doneBtn setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.5] forState:UIControlStateDisabled];
  3470. _doneBtn.layer.cornerRadius = 3;
  3471. _doneBtn.enabled = NO;
  3472. [_doneBtn addTarget:self action:@selector(didDoneBtnClick) forControlEvents:UIControlEventTouchUpInside];
  3473. }
  3474. return _doneBtn;
  3475. }
  3476. - (UIButton *)originalBtn {
  3477. if (!_originalBtn) {
  3478. _originalBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  3479. [_originalBtn setTitle:[NSBundle hx_localizedStringForKey:@"原图"] forState:UIControlStateNormal];
  3480. [_originalBtn addTarget:self action:@selector(didOriginalClick:) forControlEvents:UIControlEventTouchUpInside];
  3481. _originalBtn.titleLabel.font = [UIFont systemFontOfSize:16];
  3482. _originalBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  3483. }
  3484. return _originalBtn;
  3485. }
  3486. - (UIButton *)editBtn {
  3487. if (!_editBtn) {
  3488. _editBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  3489. [_editBtn setTitle:[NSBundle hx_localizedStringForKey:@"编辑"] forState:UIControlStateNormal];
  3490. _editBtn.titleLabel.font = [UIFont systemFontOfSize:16];
  3491. _editBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  3492. [_editBtn addTarget:self action:@selector(didEditBtnClick) forControlEvents:UIControlEventTouchUpInside];
  3493. _editBtn.enabled = NO;
  3494. }
  3495. return _editBtn;
  3496. }
  3497. - (UIActivityIndicatorView *)loadingView {
  3498. if (!_loadingView) {
  3499. _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
  3500. _loadingView.hidden = YES;
  3501. [self addSubview:_loadingView];
  3502. }
  3503. return _loadingView;
  3504. }
  3505. @end