// // TZAssetCell.m // TZImagePickerController // // Created by 谭真 on 15/12/24. // Copyright © 2015年 谭真. All rights reserved. // #import "TZAssetCell.h" #import "TZAssetModel.h" #import "UIView+Layout.h" #import "TZImageManager.h" #import "TZImagePickerController.h" #import "TZProgressView.h" @interface TZAssetCell () @property (weak, nonatomic) UIImageView *imageView; // The photo / 照片 @property (weak, nonatomic) UIImageView *selectImageView; @property (weak, nonatomic) UIImageView *checkImageView; @property (weak, nonatomic) UILabel *indexLabel; @property (weak, nonatomic) UIView *bottomView; @property (weak, nonatomic) UILabel *timeLength; @property (strong, nonatomic) UITapGestureRecognizer *tapGesture; /** 长按手势(用于视频触发视频预览) */ @property (strong, nonatomic) UILongPressGestureRecognizer * longPressGestrue ; @property (nonatomic, weak) UIImageView *videoImgView; @property (nonatomic, strong) TZProgressView *progressView; @property (nonatomic, assign) int32_t bigImageRequestID; @end @implementation TZAssetCell - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reload:) name:@"TZ_PHOTO_PICKER_RELOAD_NOTIFICATION" object:nil]; return self; } - (void)setModel:(TZAssetModel *)model { _model = model; self.representedAssetIdentifier = model.asset.localIdentifier; int32_t imageRequestID = [[TZImageManager manager] getPhotoWithAsset:model.asset photoWidth:self.tz_width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) { // Set the cell's thumbnail image if it's still showing the same asset. if ([self.representedAssetIdentifier isEqualToString:model.asset.localIdentifier]) { self.imageView.image = photo; } else { // NSLog(@"this cell is showing other asset"); [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID]; } if (!isDegraded) { [self hideProgressView]; self.imageRequestID = 0; } } progressHandler:nil networkAccessAllowed:NO]; if (imageRequestID && self.imageRequestID && imageRequestID != self.imageRequestID) { [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID]; // NSLog(@"cancelImageRequest %d",self.imageRequestID); } self.imageRequestID = imageRequestID; self.selectPhotoButton.selected = model.isSelected; self.selectImageView.image = self.selectPhotoButton.isSelected ? self.photoSelImage : self.photoDefImage; [self toggleCheck:model.isChecked]; self.indexLabel.hidden = !self.selectPhotoButton.isSelected; self.type = (NSInteger)model.type; // 让宽度/高度小于 最小可选照片尺寸 的图片不能选中 if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) { if (_selectImageView.hidden == NO) { self.selectPhotoButton.hidden = YES; _selectImageView.hidden = YES; } } // 如果用户选中了该图片,提前获取一下大图 if (model.isSelected) { [self requestBigImage]; } else { [self cancelBigImageRequest]; } [self setNeedsLayout]; if (self.assetCellDidSetModelBlock) { self.assetCellDidSetModelBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView); } } - (void)toggleCheck:(BOOL)state { self.model.isChecked = state; // self.checkImageView.image = self.model.isChecked ? [UIImage imageNamed:@"picker_select_1"] : [UIImage imageNamed:@"picker_select_0"]; self.checkImageView.image = self.model.isChecked ? [UIImage imageNamed:@"picker_select_1"] : nil; } - (void)setIndex:(NSInteger)index { _index = index; self.indexLabel.text = [NSString stringWithFormat:@"%zd", index]; [self.contentView bringSubviewToFront:self.indexLabel]; } - (void)setShowSelectBtn:(BOOL)showSelectBtn { _showSelectBtn = showSelectBtn; BOOL selectable = [[TZImageManager manager] isPhotoSelectableWithAsset:self.model.asset]; if (!self.selectPhotoButton.hidden) { self.selectPhotoButton.hidden = !showSelectBtn || !selectable; } if (!self.selectImageView.hidden) { self.selectImageView.hidden = !showSelectBtn || !selectable; } } - (void)setShowCheckImageView:(BOOL)showCheckImageView { _showCheckImageView = showCheckImageView; self.checkImageView.hidden = !showCheckImageView; } - (void)setType:(TZAssetCellType)type { _type = type; if (type == TZAssetCellTypePhoto || type == TZAssetCellTypeLivePhoto || (type == TZAssetCellTypePhotoGif && !self.allowPickingGif) || self.allowPickingMultipleVideo) { _selectImageView.hidden = NO; _selectPhotoButton.hidden = NO; _bottomView.hidden = YES; } else { // Video of Gif _selectImageView.hidden = YES; _selectPhotoButton.hidden = YES; } if (type == TZAssetCellTypeVideo) { self.bottomView.hidden = NO; self.timeLength.text = _model.timeLength; self.videoImgView.hidden = NO; _timeLength.tz_left = self.videoImgView.tz_right; _timeLength.textAlignment = NSTextAlignmentRight; } else if (type == TZAssetCellTypePhotoGif && self.allowPickingGif) { self.bottomView.hidden = NO; self.timeLength.text = @"GIF"; self.videoImgView.hidden = YES; _timeLength.tz_left = 5; _timeLength.textAlignment = NSTextAlignmentLeft; } } - (void)setAllowPreview:(BOOL)allowPreview { _allowPreview = allowPreview; if (allowPreview) { _imageView.userInteractionEnabled = NO; _tapGesture.enabled = NO; _longPressGestrue.enabled = NO; } else { _imageView.userInteractionEnabled = YES; _tapGesture.enabled = YES; _longPressGestrue.enabled = YES; } } - (void)selectPhotoButtonClick:(UIButton *)sender { if (self.didSelectPhotoBlock) { self.didSelectPhotoBlock(sender.isSelected); } self.selectImageView.image = sender.isSelected ? self.photoSelImage : self.photoDefImage; if (sender.isSelected) { [UIView showOscillatoryAnimationWithLayer:_selectImageView.layer type:TZOscillatoryAnimationToBigger]; // 用户选中了该图片,提前获取一下大图 [self requestBigImage]; } else { // 取消选中,取消大图的获取 [self cancelBigImageRequest]; } } /// 只在单选状态且allowPreview为NO时会有该事件 - (void)didTapImageView { if (self.didSelectPhotoBlock) { self.didSelectPhotoBlock(NO); } } - (void)didLongPressImageView:(UILongPressGestureRecognizer *)longPress { if (longPress.state == UIGestureRecognizerStateBegan) { if (self.didLongPressPhotoBlock) { self.didLongPressPhotoBlock(self.model); } } } - (void)hideProgressView { if (_progressView) { self.progressView.hidden = YES; self.imageView.alpha = 1.0; } } - (void)requestBigImage { if (_bigImageRequestID) { [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID]; } _bigImageRequestID = [[TZImageManager manager] requestImageDataForAsset:_model.asset completion:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { [self hideProgressView]; } progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { if (self.model.isSelected) { progress = progress > 0.02 ? progress : 0.02;; self.progressView.progress = progress; self.progressView.hidden = NO; self.imageView.alpha = 0.4; if (progress >= 1) { [self hideProgressView]; } } else { // 快速连续点几次,会EXC_BAD_ACCESS... // *stop = YES; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [self cancelBigImageRequest]; } }]; } - (void)cancelBigImageRequest { if (_bigImageRequestID) { [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID]; } [self hideProgressView]; } #pragma mark - Notification - (void)reload:(NSNotification *)noti { TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)noti.object; if (self.model.isSelected && tzImagePickerVc.showSelectedIndex) { self.index = [tzImagePickerVc.selectedAssetIds indexOfObject:self.model.asset.localIdentifier] + 1; } self.indexLabel.hidden = !self.selectPhotoButton.isSelected; if (tzImagePickerVc.selectedModels.count >= tzImagePickerVc.maxImagesCount && tzImagePickerVc.showPhotoCannotSelectLayer && !self.model.isSelected) { self.cannotSelectLayerButton.backgroundColor = tzImagePickerVc.cannotSelectLayerColor; self.cannotSelectLayerButton.hidden = NO; } else { self.cannotSelectLayerButton.hidden = YES; } } #pragma mark - Lazy load - (UIButton *)selectPhotoButton { if (_selectPhotoButton == nil) { UIButton *selectPhotoButton = [[UIButton alloc] init]; [selectPhotoButton addTarget:self action:@selector(selectPhotoButtonClick:) forControlEvents:UIControlEventTouchUpInside]; [self.contentView addSubview:selectPhotoButton]; _selectPhotoButton = selectPhotoButton; } return _selectPhotoButton; } - (UIImageView *)imageView { if (_imageView == nil) { UIImageView *imageView = [[UIImageView alloc] init]; imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; [self.contentView addSubview:imageView]; _imageView = imageView; /// 如果非视频类型 用回原来手势触发 _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapImageView)]; [_imageView addGestureRecognizer:_tapGesture]; if (_model.type == TZAssetCellTypeVideo) { /// 如果未视频类型使用长按1s触发 _longPressGestrue = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPressImageView:)]; _longPressGestrue.minimumPressDuration = 1.0; [_tapGesture requireGestureRecognizerToFail:_longPressGestrue]; [_imageView addGestureRecognizer:_longPressGestrue]; } } return _imageView; } - (UIImageView *)selectImageView { if (_selectImageView == nil) { UIImageView *selectImageView = [[UIImageView alloc] init]; selectImageView.contentMode = UIViewContentModeCenter; selectImageView.clipsToBounds = YES; [self.contentView addSubview:selectImageView]; _selectImageView = selectImageView; } return _selectImageView; } - (UIImageView *)checkImageView { if (_checkImageView == nil) { UIImageView *checkImgView = [[UIImageView alloc] init]; checkImgView.contentMode = UIViewContentModeCenter; checkImgView.clipsToBounds = YES; [self.contentView addSubview:checkImgView]; _checkImageView = checkImgView; } return _checkImageView; } - (UIView *)bottomView { if (_bottomView == nil) { UIView *bottomView = [[UIView alloc] init]; static NSInteger rgb = 0; bottomView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.8]; [self.contentView addSubview:bottomView]; _bottomView = bottomView; } return _bottomView; } - (UIButton *)cannotSelectLayerButton { if (_cannotSelectLayerButton == nil) { UIButton *cannotSelectLayerButton = [[UIButton alloc] init]; [self.contentView addSubview:cannotSelectLayerButton]; _cannotSelectLayerButton = cannotSelectLayerButton; } return _cannotSelectLayerButton; } - (UIImageView *)videoImgView { if (_videoImgView == nil) { UIImageView *videoImgView = [[UIImageView alloc] init]; [videoImgView setImage:[UIImage tz_imageNamedFromMyBundle:@"VideoSendIcon"]]; [self.bottomView addSubview:videoImgView]; _videoImgView = videoImgView; } return _videoImgView; } - (UILabel *)timeLength { if (_timeLength == nil) { UILabel *timeLength = [[UILabel alloc] init]; timeLength.font = [UIFont boldSystemFontOfSize:11]; timeLength.textColor = [UIColor whiteColor]; timeLength.textAlignment = NSTextAlignmentRight; [self.bottomView addSubview:timeLength]; _timeLength = timeLength; } return _timeLength; } - (UILabel *)indexLabel { if (_indexLabel == nil) { UILabel *indexLabel = [[UILabel alloc] init]; indexLabel.font = [UIFont systemFontOfSize:14]; indexLabel.textColor = [UIColor whiteColor]; indexLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:indexLabel]; _indexLabel = indexLabel; } return _indexLabel; } - (TZProgressView *)progressView { if (_progressView == nil) { _progressView = [[TZProgressView alloc] init]; _progressView.hidden = YES; [self addSubview:_progressView]; } return _progressView; } - (void)layoutSubviews { [super layoutSubviews]; _cannotSelectLayerButton.frame = self.bounds; if (self.allowPreview) { _selectPhotoButton.frame = CGRectMake(self.tz_width - 44, 0, 44, 44); } else { _selectPhotoButton.frame = self.bounds; } _selectImageView.frame = CGRectMake(self.tz_width - 27, 3, 24, 24); _checkImageView.frame = CGRectMake(self.tz_width - (16+4.0), 4.0, 16, 16); if (_selectImageView.image.size.width <= 27) { _selectImageView.contentMode = UIViewContentModeCenter; } else { _selectImageView.contentMode = UIViewContentModeScaleAspectFit; } _indexLabel.frame = _selectImageView.frame; _imageView.frame = CGRectMake(0, 0, self.tz_width, self.tz_height); static CGFloat progressWH = 20; CGFloat progressXY = (self.tz_width - progressWH) / 2; _progressView.frame = CGRectMake(progressXY, progressXY, progressWH, progressWH); _bottomView.frame = CGRectMake(0, self.tz_height - 17, self.tz_width, 17); _videoImgView.frame = CGRectMake(8, 0, 17, 17); _timeLength.frame = CGRectMake(self.videoImgView.tz_right, 0, self.tz_width - self.videoImgView.tz_right - 5, 17); self.type = (NSInteger)self.model.type; self.showSelectBtn = self.showSelectBtn; [self.contentView bringSubviewToFront:_bottomView]; [self.contentView bringSubviewToFront:_cannotSelectLayerButton]; [self.contentView bringSubviewToFront:_selectPhotoButton]; [self.contentView bringSubviewToFront:_selectImageView]; [self.contentView bringSubviewToFront:_checkImageView]; [self.contentView bringSubviewToFront:_indexLabel]; if (self.assetCellDidLayoutSubviewsBlock) { self.assetCellDidLayoutSubviewsBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView); } } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end @interface TZAlbumCell () @property (weak, nonatomic) UIImageView *posterImageView; @property (weak, nonatomic) UILabel *titleLabel; @end @implementation TZAlbumCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; self.selectionStyle = UITableViewCellSelectionStyleNone; self.backgroundColor = [UIColor colorWithRed:30/255.0 green:30/255.0 blue:42/255.0 alpha:1.0]; self.contentView.backgroundColor = [UIColor colorWithRed:30/255.0 green:30/255.0 blue:42/255.0 alpha:1.0]; self.separatorInset = UIEdgeInsetsMake(0, 16, 0, 16); return self; } - (void)setModel:(TZAlbumModel *)model { _model = model; NSMutableAttributedString *nameString = [[NSMutableAttributedString alloc] initWithString:model.name attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor blackColor]}]; NSAttributedString *countString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" (%zd)",model.count] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor lightGrayColor]}]; [nameString appendAttributedString:countString]; self.titleLabel.attributedText = nameString; [[TZImageManager manager] getPostImageWithAlbumModel:model completion:^(UIImage *postImage) { self.posterImageView.image = postImage; }]; if (model.selectedCount) { self.selectedCountButton.hidden = NO; [self.selectedCountButton setTitle:[NSString stringWithFormat:@"%zd",model.selectedCount] forState:UIControlStateNormal]; } else { self.selectedCountButton.hidden = YES; } if (self.albumCellDidSetModelBlock) { self.albumCellDidSetModelBlock(self, _posterImageView, _titleLabel); } } - (void)layoutSubviews { [super layoutSubviews]; _selectedCountButton.frame = CGRectMake(self.contentView.tz_width - 24, 23, 24, 24); NSInteger titleHeight = ceil(self.titleLabel.font.lineHeight); self.titleLabel.frame = CGRectMake(80, (self.tz_height - titleHeight) / 2, self.tz_width - 80 - 50, titleHeight); self.posterImageView.frame = CGRectMake(0, 0, 70, 70); if (self.albumCellDidLayoutSubviewsBlock) { self.albumCellDidLayoutSubviewsBlock(self, _posterImageView, _titleLabel); } } - (void)layoutSublayersOfLayer:(CALayer *)layer { [super layoutSublayersOfLayer:layer]; } #pragma mark - Lazy load - (UIImageView *)posterImageView { if (_posterImageView == nil) { UIImageView *posterImageView = [[UIImageView alloc] init]; posterImageView.contentMode = UIViewContentModeScaleAspectFill; posterImageView.clipsToBounds = YES; posterImageView.layer.cornerRadius = 4.0; [self.contentView addSubview:posterImageView]; _posterImageView = posterImageView; } return _posterImageView; } - (UILabel *)titleLabel { if (_titleLabel == nil) { UILabel *titleLabel = [[UILabel alloc] init]; titleLabel.font = [UIFont boldSystemFontOfSize:17]; titleLabel.textColor = [UIColor blackColor]; titleLabel.textAlignment = NSTextAlignmentLeft; [self.contentView addSubview:titleLabel]; _titleLabel = titleLabel; } return _titleLabel; } - (UIButton *)selectedCountButton { if (_selectedCountButton == nil) { UIButton *selectedCountButton = [[UIButton alloc] init]; selectedCountButton.layer.cornerRadius = 12; selectedCountButton.clipsToBounds = YES; selectedCountButton.backgroundColor = [UIColor redColor]; [selectedCountButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; selectedCountButton.titleLabel.font = [UIFont systemFontOfSize:15]; [self.contentView addSubview:selectedCountButton]; _selectedCountButton = selectedCountButton; } return _selectedCountButton; } @end @implementation TZAssetCameraCell - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; _imageView = [[UIImageView alloc] init]; _imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500]; _imageView.contentMode = UIViewContentModeScaleAspectFill; [self.contentView addSubview:_imageView]; self.clipsToBounds = YES; } return self; } - (void)layoutSubviews { [super layoutSubviews]; _imageView.frame = self.bounds; } @end