TZAssetCell.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. //
  2. // TZAssetCell.m
  3. // TZImagePickerController
  4. //
  5. // Created by 谭真 on 15/12/24.
  6. // Copyright © 2015年 谭真. All rights reserved.
  7. //
  8. #import "TZAssetCell.h"
  9. #import "TZAssetModel.h"
  10. #import "UIView+Layout.h"
  11. #import "TZImageManager.h"
  12. #import "TZImagePickerController.h"
  13. #import "TZProgressView.h"
  14. @interface TZAssetCell ()
  15. @property (weak, nonatomic) UIImageView *imageView; // The photo / 照片
  16. @property (weak, nonatomic) UIImageView *selectImageView;
  17. @property (weak, nonatomic) UIImageView *checkImageView;
  18. @property (weak, nonatomic) UILabel *indexLabel;
  19. @property (weak, nonatomic) UIView *bottomView;
  20. @property (weak, nonatomic) UILabel *timeLength;
  21. @property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
  22. /** 长按手势(用于视频触发视频预览) */
  23. @property (strong, nonatomic) UILongPressGestureRecognizer * longPressGestrue ;
  24. @property (nonatomic, weak) UIImageView *videoImgView;
  25. @property (nonatomic, strong) TZProgressView *progressView;
  26. @property (nonatomic, assign) int32_t bigImageRequestID;
  27. @end
  28. @implementation TZAssetCell
  29. - (instancetype)initWithFrame:(CGRect)frame {
  30. self = [super initWithFrame:frame];
  31. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reload:) name:@"TZ_PHOTO_PICKER_RELOAD_NOTIFICATION" object:nil];
  32. return self;
  33. }
  34. - (void)setModel:(TZAssetModel *)model {
  35. _model = model;
  36. self.representedAssetIdentifier = model.asset.localIdentifier;
  37. int32_t imageRequestID = [[TZImageManager manager] getPhotoWithAsset:model.asset photoWidth:self.tz_width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
  38. // Set the cell's thumbnail image if it's still showing the same asset.
  39. if ([self.representedAssetIdentifier isEqualToString:model.asset.localIdentifier]) {
  40. self.imageView.image = photo;
  41. } else {
  42. // NSLog(@"this cell is showing other asset");
  43. [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
  44. }
  45. if (!isDegraded) {
  46. [self hideProgressView];
  47. self.imageRequestID = 0;
  48. }
  49. } progressHandler:nil networkAccessAllowed:NO];
  50. if (imageRequestID && self.imageRequestID && imageRequestID != self.imageRequestID) {
  51. [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
  52. // NSLog(@"cancelImageRequest %d",self.imageRequestID);
  53. }
  54. self.imageRequestID = imageRequestID;
  55. self.selectPhotoButton.selected = model.isSelected;
  56. self.selectImageView.image = self.selectPhotoButton.isSelected ? self.photoSelImage : self.photoDefImage;
  57. [self toggleCheck:model.isChecked];
  58. self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
  59. self.type = (NSInteger)model.type;
  60. // 让宽度/高度小于 最小可选照片尺寸 的图片不能选中
  61. if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) {
  62. if (_selectImageView.hidden == NO) {
  63. self.selectPhotoButton.hidden = YES;
  64. _selectImageView.hidden = YES;
  65. }
  66. }
  67. // 如果用户选中了该图片,提前获取一下大图
  68. if (model.isSelected) {
  69. [self requestBigImage];
  70. } else {
  71. [self cancelBigImageRequest];
  72. }
  73. [self setNeedsLayout];
  74. if (self.assetCellDidSetModelBlock) {
  75. self.assetCellDidSetModelBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
  76. }
  77. }
  78. - (void)toggleCheck:(BOOL)state {
  79. self.model.isChecked = state;
  80. // self.checkImageView.image = self.model.isChecked ? [UIImage imageNamed:@"picker_select_1"] : [UIImage imageNamed:@"picker_select_0"];
  81. self.checkImageView.image = self.model.isChecked ? [UIImage imageNamed:@"picker_select_1"] : nil;
  82. }
  83. - (void)setIndex:(NSInteger)index {
  84. _index = index;
  85. self.indexLabel.text = [NSString stringWithFormat:@"%zd", index];
  86. [self.contentView bringSubviewToFront:self.indexLabel];
  87. }
  88. - (void)setShowSelectBtn:(BOOL)showSelectBtn {
  89. _showSelectBtn = showSelectBtn;
  90. BOOL selectable = [[TZImageManager manager] isPhotoSelectableWithAsset:self.model.asset];
  91. if (!self.selectPhotoButton.hidden) {
  92. self.selectPhotoButton.hidden = !showSelectBtn || !selectable;
  93. }
  94. if (!self.selectImageView.hidden) {
  95. self.selectImageView.hidden = !showSelectBtn || !selectable;
  96. }
  97. }
  98. - (void)setShowCheckImageView:(BOOL)showCheckImageView {
  99. _showCheckImageView = showCheckImageView;
  100. self.checkImageView.hidden = !showCheckImageView;
  101. }
  102. - (void)setType:(TZAssetCellType)type {
  103. _type = type;
  104. if (type == TZAssetCellTypePhoto || type == TZAssetCellTypeLivePhoto || (type == TZAssetCellTypePhotoGif && !self.allowPickingGif) || self.allowPickingMultipleVideo) {
  105. _selectImageView.hidden = NO;
  106. _selectPhotoButton.hidden = NO;
  107. _bottomView.hidden = YES;
  108. } else { // Video of Gif
  109. _selectImageView.hidden = YES;
  110. _selectPhotoButton.hidden = YES;
  111. }
  112. if (type == TZAssetCellTypeVideo) {
  113. self.bottomView.hidden = NO;
  114. self.timeLength.text = _model.timeLength;
  115. self.videoImgView.hidden = NO;
  116. _timeLength.tz_left = self.videoImgView.tz_right;
  117. _timeLength.textAlignment = NSTextAlignmentRight;
  118. } else if (type == TZAssetCellTypePhotoGif && self.allowPickingGif) {
  119. self.bottomView.hidden = NO;
  120. self.timeLength.text = @"GIF";
  121. self.videoImgView.hidden = YES;
  122. _timeLength.tz_left = 5;
  123. _timeLength.textAlignment = NSTextAlignmentLeft;
  124. }
  125. }
  126. - (void)setAllowPreview:(BOOL)allowPreview {
  127. _allowPreview = allowPreview;
  128. if (allowPreview) {
  129. _imageView.userInteractionEnabled = NO;
  130. _tapGesture.enabled = NO;
  131. _longPressGestrue.enabled = NO;
  132. } else {
  133. _imageView.userInteractionEnabled = YES;
  134. _tapGesture.enabled = YES;
  135. _longPressGestrue.enabled = YES;
  136. }
  137. }
  138. - (void)selectPhotoButtonClick:(UIButton *)sender {
  139. if (self.didSelectPhotoBlock) {
  140. self.didSelectPhotoBlock(sender.isSelected);
  141. }
  142. self.selectImageView.image = sender.isSelected ? self.photoSelImage : self.photoDefImage;
  143. if (sender.isSelected) {
  144. [UIView showOscillatoryAnimationWithLayer:_selectImageView.layer type:TZOscillatoryAnimationToBigger];
  145. // 用户选中了该图片,提前获取一下大图
  146. [self requestBigImage];
  147. } else { // 取消选中,取消大图的获取
  148. [self cancelBigImageRequest];
  149. }
  150. }
  151. /// 只在单选状态且allowPreview为NO时会有该事件
  152. - (void)didTapImageView {
  153. if (self.didSelectPhotoBlock) {
  154. self.didSelectPhotoBlock(NO);
  155. }
  156. }
  157. - (void)didLongPressImageView:(UILongPressGestureRecognizer *)longPress {
  158. if (longPress.state == UIGestureRecognizerStateBegan) {
  159. if (self.didLongPressPhotoBlock) {
  160. self.didLongPressPhotoBlock(self.model);
  161. }
  162. }
  163. }
  164. - (void)hideProgressView {
  165. if (_progressView) {
  166. self.progressView.hidden = YES;
  167. self.imageView.alpha = 1.0;
  168. }
  169. }
  170. - (void)requestBigImage {
  171. if (_bigImageRequestID) {
  172. [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
  173. }
  174. _bigImageRequestID = [[TZImageManager manager] requestImageDataForAsset:_model.asset completion:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
  175. [self hideProgressView];
  176. } progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
  177. if (self.model.isSelected) {
  178. progress = progress > 0.02 ? progress : 0.02;;
  179. self.progressView.progress = progress;
  180. self.progressView.hidden = NO;
  181. self.imageView.alpha = 0.4;
  182. if (progress >= 1) {
  183. [self hideProgressView];
  184. }
  185. } else {
  186. // 快速连续点几次,会EXC_BAD_ACCESS...
  187. // *stop = YES;
  188. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  189. [self cancelBigImageRequest];
  190. }
  191. }];
  192. }
  193. - (void)cancelBigImageRequest {
  194. if (_bigImageRequestID) {
  195. [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
  196. }
  197. [self hideProgressView];
  198. }
  199. #pragma mark - Notification
  200. - (void)reload:(NSNotification *)noti {
  201. TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)noti.object;
  202. if (self.model.isSelected && tzImagePickerVc.showSelectedIndex) {
  203. self.index = [tzImagePickerVc.selectedAssetIds indexOfObject:self.model.asset.localIdentifier] + 1;
  204. }
  205. self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
  206. if (tzImagePickerVc.selectedModels.count >= tzImagePickerVc.maxImagesCount && tzImagePickerVc.showPhotoCannotSelectLayer && !self.model.isSelected) {
  207. self.cannotSelectLayerButton.backgroundColor = tzImagePickerVc.cannotSelectLayerColor;
  208. self.cannotSelectLayerButton.hidden = NO;
  209. } else {
  210. self.cannotSelectLayerButton.hidden = YES;
  211. }
  212. }
  213. #pragma mark - Lazy load
  214. - (UIButton *)selectPhotoButton {
  215. if (_selectPhotoButton == nil) {
  216. UIButton *selectPhotoButton = [[UIButton alloc] init];
  217. [selectPhotoButton addTarget:self action:@selector(selectPhotoButtonClick:) forControlEvents:UIControlEventTouchUpInside];
  218. [self.contentView addSubview:selectPhotoButton];
  219. _selectPhotoButton = selectPhotoButton;
  220. }
  221. return _selectPhotoButton;
  222. }
  223. - (UIImageView *)imageView {
  224. if (_imageView == nil) {
  225. UIImageView *imageView = [[UIImageView alloc] init];
  226. imageView.contentMode = UIViewContentModeScaleAspectFill;
  227. imageView.clipsToBounds = YES;
  228. [self.contentView addSubview:imageView];
  229. _imageView = imageView;
  230. /// 如果非视频类型 用回原来手势触发
  231. _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapImageView)];
  232. [_imageView addGestureRecognizer:_tapGesture];
  233. if (_model.type == TZAssetCellTypeVideo) {
  234. /// 如果未视频类型使用长按1s触发
  235. _longPressGestrue = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPressImageView:)];
  236. _longPressGestrue.minimumPressDuration = 1.0;
  237. [_tapGesture requireGestureRecognizerToFail:_longPressGestrue];
  238. [_imageView addGestureRecognizer:_longPressGestrue];
  239. }
  240. }
  241. return _imageView;
  242. }
  243. - (UIImageView *)selectImageView {
  244. if (_selectImageView == nil) {
  245. UIImageView *selectImageView = [[UIImageView alloc] init];
  246. selectImageView.contentMode = UIViewContentModeCenter;
  247. selectImageView.clipsToBounds = YES;
  248. [self.contentView addSubview:selectImageView];
  249. _selectImageView = selectImageView;
  250. }
  251. return _selectImageView;
  252. }
  253. - (UIImageView *)checkImageView {
  254. if (_checkImageView == nil) {
  255. UIImageView *checkImgView = [[UIImageView alloc] init];
  256. checkImgView.contentMode = UIViewContentModeCenter;
  257. checkImgView.clipsToBounds = YES;
  258. [self.contentView addSubview:checkImgView];
  259. _checkImageView = checkImgView;
  260. }
  261. return _checkImageView;
  262. }
  263. - (UIView *)bottomView {
  264. if (_bottomView == nil) {
  265. UIView *bottomView = [[UIView alloc] init];
  266. static NSInteger rgb = 0;
  267. bottomView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.8];
  268. [self.contentView addSubview:bottomView];
  269. _bottomView = bottomView;
  270. }
  271. return _bottomView;
  272. }
  273. - (UIButton *)cannotSelectLayerButton {
  274. if (_cannotSelectLayerButton == nil) {
  275. UIButton *cannotSelectLayerButton = [[UIButton alloc] init];
  276. [self.contentView addSubview:cannotSelectLayerButton];
  277. _cannotSelectLayerButton = cannotSelectLayerButton;
  278. }
  279. return _cannotSelectLayerButton;
  280. }
  281. - (UIImageView *)videoImgView {
  282. if (_videoImgView == nil) {
  283. UIImageView *videoImgView = [[UIImageView alloc] init];
  284. [videoImgView setImage:[UIImage tz_imageNamedFromMyBundle:@"VideoSendIcon"]];
  285. [self.bottomView addSubview:videoImgView];
  286. _videoImgView = videoImgView;
  287. }
  288. return _videoImgView;
  289. }
  290. - (UILabel *)timeLength {
  291. if (_timeLength == nil) {
  292. UILabel *timeLength = [[UILabel alloc] init];
  293. timeLength.font = [UIFont boldSystemFontOfSize:11];
  294. timeLength.textColor = [UIColor whiteColor];
  295. timeLength.textAlignment = NSTextAlignmentRight;
  296. [self.bottomView addSubview:timeLength];
  297. _timeLength = timeLength;
  298. }
  299. return _timeLength;
  300. }
  301. - (UILabel *)indexLabel {
  302. if (_indexLabel == nil) {
  303. UILabel *indexLabel = [[UILabel alloc] init];
  304. indexLabel.font = [UIFont systemFontOfSize:14];
  305. indexLabel.textColor = [UIColor whiteColor];
  306. indexLabel.textAlignment = NSTextAlignmentCenter;
  307. [self.contentView addSubview:indexLabel];
  308. _indexLabel = indexLabel;
  309. }
  310. return _indexLabel;
  311. }
  312. - (TZProgressView *)progressView {
  313. if (_progressView == nil) {
  314. _progressView = [[TZProgressView alloc] init];
  315. _progressView.hidden = YES;
  316. [self addSubview:_progressView];
  317. }
  318. return _progressView;
  319. }
  320. - (void)layoutSubviews {
  321. [super layoutSubviews];
  322. _cannotSelectLayerButton.frame = self.bounds;
  323. if (self.allowPreview) {
  324. _selectPhotoButton.frame = CGRectMake(self.tz_width - 44, 0, 44, 44);
  325. } else {
  326. _selectPhotoButton.frame = self.bounds;
  327. }
  328. _selectImageView.frame = CGRectMake(self.tz_width - 27, 3, 24, 24);
  329. _checkImageView.frame = CGRectMake(self.tz_width - (16+4.0), 4.0, 16, 16);
  330. if (_selectImageView.image.size.width <= 27) {
  331. _selectImageView.contentMode = UIViewContentModeCenter;
  332. } else {
  333. _selectImageView.contentMode = UIViewContentModeScaleAspectFit;
  334. }
  335. _indexLabel.frame = _selectImageView.frame;
  336. _imageView.frame = CGRectMake(0, 0, self.tz_width, self.tz_height);
  337. static CGFloat progressWH = 20;
  338. CGFloat progressXY = (self.tz_width - progressWH) / 2;
  339. _progressView.frame = CGRectMake(progressXY, progressXY, progressWH, progressWH);
  340. _bottomView.frame = CGRectMake(0, self.tz_height - 17, self.tz_width, 17);
  341. _videoImgView.frame = CGRectMake(8, 0, 17, 17);
  342. _timeLength.frame = CGRectMake(self.videoImgView.tz_right, 0, self.tz_width - self.videoImgView.tz_right - 5, 17);
  343. self.type = (NSInteger)self.model.type;
  344. self.showSelectBtn = self.showSelectBtn;
  345. [self.contentView bringSubviewToFront:_bottomView];
  346. [self.contentView bringSubviewToFront:_cannotSelectLayerButton];
  347. [self.contentView bringSubviewToFront:_selectPhotoButton];
  348. [self.contentView bringSubviewToFront:_selectImageView];
  349. [self.contentView bringSubviewToFront:_checkImageView];
  350. [self.contentView bringSubviewToFront:_indexLabel];
  351. if (self.assetCellDidLayoutSubviewsBlock) {
  352. self.assetCellDidLayoutSubviewsBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
  353. }
  354. }
  355. - (void)dealloc {
  356. [[NSNotificationCenter defaultCenter] removeObserver:self];
  357. }
  358. @end
  359. @interface TZAlbumCell ()
  360. @property (weak, nonatomic) UIImageView *posterImageView;
  361. @property (weak, nonatomic) UILabel *titleLabel;
  362. @end
  363. @implementation TZAlbumCell
  364. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  365. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  366. self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  367. self.selectionStyle = UITableViewCellSelectionStyleNone;
  368. self.backgroundColor = [UIColor colorWithRed:30/255.0 green:30/255.0 blue:42/255.0 alpha:1.0];
  369. self.contentView.backgroundColor = [UIColor colorWithRed:30/255.0 green:30/255.0 blue:42/255.0 alpha:1.0];
  370. self.separatorInset = UIEdgeInsetsMake(0, 16, 0, 16);
  371. return self;
  372. }
  373. - (void)setModel:(TZAlbumModel *)model {
  374. _model = model;
  375. NSMutableAttributedString *nameString = [[NSMutableAttributedString alloc] initWithString:model.name attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor blackColor]}];
  376. NSAttributedString *countString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" (%zd)",model.count] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor lightGrayColor]}];
  377. [nameString appendAttributedString:countString];
  378. self.titleLabel.attributedText = nameString;
  379. [[TZImageManager manager] getPostImageWithAlbumModel:model completion:^(UIImage *postImage) {
  380. self.posterImageView.image = postImage;
  381. }];
  382. if (model.selectedCount) {
  383. self.selectedCountButton.hidden = NO;
  384. [self.selectedCountButton setTitle:[NSString stringWithFormat:@"%zd",model.selectedCount] forState:UIControlStateNormal];
  385. } else {
  386. self.selectedCountButton.hidden = YES;
  387. }
  388. if (self.albumCellDidSetModelBlock) {
  389. self.albumCellDidSetModelBlock(self, _posterImageView, _titleLabel);
  390. }
  391. }
  392. - (void)layoutSubviews {
  393. [super layoutSubviews];
  394. _selectedCountButton.frame = CGRectMake(self.contentView.tz_width - 24, 23, 24, 24);
  395. NSInteger titleHeight = ceil(self.titleLabel.font.lineHeight);
  396. self.titleLabel.frame = CGRectMake(80, (self.tz_height - titleHeight) / 2, self.tz_width - 80 - 50, titleHeight);
  397. self.posterImageView.frame = CGRectMake(0, 0, 70, 70);
  398. if (self.albumCellDidLayoutSubviewsBlock) {
  399. self.albumCellDidLayoutSubviewsBlock(self, _posterImageView, _titleLabel);
  400. }
  401. }
  402. - (void)layoutSublayersOfLayer:(CALayer *)layer {
  403. [super layoutSublayersOfLayer:layer];
  404. }
  405. #pragma mark - Lazy load
  406. - (UIImageView *)posterImageView {
  407. if (_posterImageView == nil) {
  408. UIImageView *posterImageView = [[UIImageView alloc] init];
  409. posterImageView.contentMode = UIViewContentModeScaleAspectFill;
  410. posterImageView.clipsToBounds = YES;
  411. posterImageView.layer.cornerRadius = 4.0;
  412. [self.contentView addSubview:posterImageView];
  413. _posterImageView = posterImageView;
  414. }
  415. return _posterImageView;
  416. }
  417. - (UILabel *)titleLabel {
  418. if (_titleLabel == nil) {
  419. UILabel *titleLabel = [[UILabel alloc] init];
  420. titleLabel.font = [UIFont boldSystemFontOfSize:17];
  421. titleLabel.textColor = [UIColor blackColor];
  422. titleLabel.textAlignment = NSTextAlignmentLeft;
  423. [self.contentView addSubview:titleLabel];
  424. _titleLabel = titleLabel;
  425. }
  426. return _titleLabel;
  427. }
  428. - (UIButton *)selectedCountButton {
  429. if (_selectedCountButton == nil) {
  430. UIButton *selectedCountButton = [[UIButton alloc] init];
  431. selectedCountButton.layer.cornerRadius = 12;
  432. selectedCountButton.clipsToBounds = YES;
  433. selectedCountButton.backgroundColor = [UIColor redColor];
  434. [selectedCountButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  435. selectedCountButton.titleLabel.font = [UIFont systemFontOfSize:15];
  436. [self.contentView addSubview:selectedCountButton];
  437. _selectedCountButton = selectedCountButton;
  438. }
  439. return _selectedCountButton;
  440. }
  441. @end
  442. @implementation TZAssetCameraCell
  443. - (instancetype)initWithFrame:(CGRect)frame {
  444. self = [super initWithFrame:frame];
  445. if (self) {
  446. self.backgroundColor = [UIColor whiteColor];
  447. _imageView = [[UIImageView alloc] init];
  448. _imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
  449. _imageView.contentMode = UIViewContentModeScaleAspectFill;
  450. [self.contentView addSubview:_imageView];
  451. self.clipsToBounds = YES;
  452. }
  453. return self;
  454. }
  455. - (void)layoutSubviews {
  456. [super layoutSubviews];
  457. _imageView.frame = self.bounds;
  458. }
  459. @end