iOS開發(fā) 自定義相冊(cè)鍵盤

現(xiàn)在很多app都有用到相冊(cè)選擇等功能,網(wǎng)上也已經(jīng)有了很多封裝好了的第三方庫(kù),但是最近項(xiàng)目中,設(shè)計(jì)師突發(fā)奇想,想要節(jié)省用戶選擇成本,讓我們實(shí)現(xiàn)相冊(cè)鍵盤,不用跳轉(zhuǎn)新的頁(yè)面可以直接選擇照片或者視頻,類似于圖中的樣式:

圖1.0

然后第一個(gè)想法,網(wǎng)上找輪子,然后找了一圈,并沒有發(fā)現(xiàn)適用的,只好自己實(shí)現(xiàn)了。

我用的方法是利用UICollectionView實(shí)現(xiàn),接下來貼上代碼。

1.首先做好準(zhǔn)備工作,在pod文件中導(dǎo)入下列第三方庫(kù):

? pod ?'YBImageBrowser',' ~> 2.1.5'????????

? pod ?'SDWebImage',' ~> 4.4.6'

? pod ?'Toast'

? pod ?'Masonry',' ~> 1.1.0'

? pod ?'SJVideoPlayer'

這些大都是常用的第三方庫(kù),從上到下的功能分別是:圖片查看、圖片加載、Toast提示、頁(yè)面布局、視頻播放。

2.然后在info.plist文件中添加相冊(cè)權(quán)限提示:

圖2

3.開始寫代碼,導(dǎo)入相應(yīng)頭文件和設(shè)置好相應(yīng)的協(xié)議還有數(shù)據(jù)

#import "ViewController.h"

#import?<SDWebImage/UIImageView+WebCache.h>

#import "YBImageBrowser.h"

#import?<Photos/Photos.h>

#import "Masonry.h"

#import "UIView+Toast.h"

#import "HobbiesCollectionViewCell.h"

#import "TZImagePickerController.h"

#import "YJVideoController.h"

#import "VideoPlayViewController.h"

@interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,UINavigationControllerDelegate,UIImagePickerControllerDelegate,YBImageBrowserDataSource,UIGestureRecognizerDelegate,TZImagePickerControllerDelegate>

{

? ? UICollectionView*myCollectionView;? ? ? ? ? ? //相冊(cè)瀑布流

? ? NSMutableArray*imageArray;? ? ? ? ? ? ? ? ? ? //圖片數(shù)組

? ? NSMutableArray*selectArray;? ? ? ? ? ? ? ? ? ? //圖片選擇數(shù)組

? ? NSMutableArray*phArray;? ? ? ? ? ? ? ? ? ? ? ? //媒體數(shù)據(jù)數(shù)組

? ? NSIntegernums;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //最大可選擇的照片數(shù)量

? ? NSInteger? IorV;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //視頻還是照片 -1:未選擇? 0:照片? 1:視頻

? ? UIView*bottomV;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //相冊(cè)所在的父視圖

? ? UIView*toolView;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //相冊(cè)上方的工具視圖(可自定義)

? ? UISwipeGestureRecognizer* recognizerUp;? ? ? ? //上滑手勢(shì)

? ? UISwipeGestureRecognizer* recognizerDown;? ? ? //下拉手勢(shì)

? ? BOOLisTop;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //是否滑動(dòng)到頂部

? ? BOOLUPorDown;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //是否是在全屏狀態(tài)

? ? NSIntegerpage;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //頁(yè)碼

? ? BOOLready;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //是否準(zhǔn)備好再次刷新

}

@property(nonatomic,strong) UIImagePickerController *imagePicker;

@end

4.開始進(jìn)入時(shí)候檢查權(quán)限

-(void)checkPermissions

{

? ? [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {

? ? ? ? if (status == PHAuthorizationStatusAuthorized) {

? ? ? ? ? ? dispatch_main_async_safe(^{

? ? ? ? ? ? ? ? [selfloadImageArray];

? ? ? ? ? ? });

? ? ? ? }else{

? ? ? ? ? ? //未獲取相冊(cè)權(quán)限

? ? ? ? ? ? [self showAlrtToSetting];

? ? ? ? }

? ? }];

}

/**

?檢測(cè)到未開啟相冊(cè)權(quán)限之后的提醒

?*/

-(void) showAlrtToSetting

{

? ? UIAlertController* alert = [UIAlertControlleralertControllerWithTitle:@"開啟相冊(cè)權(quán)限"message:@"打開相冊(cè)權(quán)限,上傳您喜歡的圖片"preferredStyle:UIAlertControllerStyleAlert];

? ? UIAlertAction* cancelAction = [UIAlertActionactionWithTitle:@"再看看"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*_Nonnullaction) {


? ? }];

? ? UIAlertAction * setAction = [UIAlertAction actionWithTitle:@"打開" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSURL* url = [NSURLURLWithString:UIApplicationOpenSettingsURLString];

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if([[UIApplicationsharedApplication]canOpenURL:url])

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [[UIApplicationsharedApplication]openURL:urloptions:@{}completionHandler:^(BOOLsuccess) {

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_main_async_safe(^{

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [selfloadImageArray];

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }];

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }];

? ? [alertaddAction:cancelAction];

? ? [alertaddAction:setAction];

? ? [self presentViewController:alert animated:YES completion:nil];

}

5.然后初始化視圖

-(void)initUI

{

? ? self.view.backgroundColor = [UIColor lightGrayColor];

? ? nums=0;

? ? IorV= -1;

? ? ready=YES;

? ? isTop=NO;

? ? page=0;


? ? toolView = [[UIView alloc] initWithFrame:CGRectMake(0, HEIGHT-221-kSafeAreaBottomHeight-44, WIDTH, 44)];

? ? toolView.backgroundColor = [UIColor whiteColor];

? ? toolView.tag=88;

? ? [self.viewaddSubview:toolView];


? ? bottomV= [[UIViewalloc]init];

? ? [self.viewaddSubview:bottomV];

? ? [bottomV mas_makeConstraints:^(MASConstraintMaker *make) {

? ? ? ? make.left.right.equalTo(self.view);

? ? ? ? make.top.equalTo(toolView.mas_bottom);

? ? ? ? make.height.mas_equalTo(HEIGHT+221+kSafeAreaBottomHeight);

? ? }];


? ? //創(chuàng)建一個(gè)layout布局類

? ? UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc]init];

? ? //設(shè)置布局方向?yàn)榇怪绷鞑季?/i>

? ? layout.scrollDirection = UICollectionViewScrollDirectionVertical;

? ? //設(shè)置每個(gè)item的大小為100*100

? ? layout.itemSize=CGSizeMake(WIDTH/4-1,WIDTH/4-1);

? ? //創(chuàng)建collectionView 通過一個(gè)布局策略layout來創(chuàng)建


? ? myCollectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 221+kSafeAreaBottomHeight) collectionViewLayout:layout];

? ? myCollectionView.delegate = self;

? ? myCollectionView.dataSource = self;

? ? myCollectionView.scrollEnabled = YES;

? ? myCollectionView.bounces = NO;

? ? myCollectionView.backgroundColor = [UIColor blackColor];

? ? //注冊(cè)Cell

? ? [myCollectionView registerNib:[UINib nibWithNibName:@"HobbiesCollectionViewCell" bundle: [NSBundle mainBundle]] forCellWithReuseIdentifier:@"HobbiesCollectionViewCell"];

? ? [bottomV addSubview:myCollectionView];

? ? recognizerUp= [[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(handleSwipeFrom:)];

? ? recognizerUp.direction = UISwipeGestureRecognizerDirectionUp;

? ? recognizerUp.delegate = self;

? ? [self.view addGestureRecognizer:recognizerUp];


? ? recognizerDown= [[UISwipeGestureRecognizeralloc]initWithTarget:selfaction:@selector(handleSwipeFrom:)];

? ? recognizerDown.direction = UISwipeGestureRecognizerDirectionDown;

? ? recognizerDown.delegate = self;

? ? [self.view addGestureRecognizer:recognizerDown];

}

6.加載本地照片和視頻數(shù)據(jù)

-(void)loadImageArray

{

? ? [self.view makeToastActivity:CENTER];

? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? // 處理耗時(shí)操作的代碼塊

? ? ? ? phArray= [NSMutableArrayarray];

? ? ? ? imageArray= [NSMutableArrayarray];

? ? ? ? PHFetchOptions *options = [[PHFetchOptions alloc] init];

? ? ? ? options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

? ? ? ? PHFetchResult*assetsFetchResults = [PHAssetfetchAssetsWithOptions:options];

? ? ? ? for(PHAsset*assetinassetsFetchResults)

? ? ? ? {

? ? ? ? ? ? //判斷本地媒體數(shù)據(jù)是照片類型和視頻類型,就加入到phArray數(shù)組中

? ? ? ? ? ? if (asset.mediaType == PHAssetMediaTypeImage || asset.mediaType == PHAssetMediaTypeVideo)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [phArrayaddObject:asset];

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? phArray=(NSMutableArray *)[[phArray reverseObjectEnumerator] allObjects];? //數(shù)組倒序排列

? ? ? ? //加載前兩百條數(shù)據(jù)(防止加載耗時(shí)過長(zhǎng))

? ? ? ? NSIntegercounts =phArray.count;

? ? ? ? if(counts>200)

? ? ? ? {

? ? ? ? ? ? counts =200;

? ? ? ? }

? ? ? ? for(inti=0;i

? ? ? ? {

? ? ? ? ? ? PHAsset*asset = [phArrayobjectAtIndex:i];

? ? ? ? ? ? PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];

? ? ? ? ? ? /** resizeMode:對(duì)請(qǐng)求的圖像怎樣縮放。有三種選擇:None,默認(rèn)加載方式;Fast,盡快地提供接近或稍微大于要求的尺寸;Exact,精準(zhǔn)提供要求的尺寸。 deliveryMode:圖像質(zhì)量。有三種值:Opportunistic,在速度與質(zhì)量中均衡;HighQualityFormat,不管花費(fèi)多長(zhǎng)時(shí)間,提供高質(zhì)量圖像;FastFormat,以最快速度提供好的質(zhì)量。

?? ? ? ? ? ? 這個(gè)屬性只有在 synchronous 為 true 時(shí)有效。

?? ? ? ? ? ? */

? ? ? ? ? ? option.resizeMode = PHImageRequestOptionsResizeModeFast;//控制照片尺寸

? ? ? ? ? ? option.deliveryMode=1;//控制照片質(zhì)量

? ? ? ? ? ? option.synchronous=YES;

? ? ? ? ? ? option.networkAccessAllowed=YES;

? ? ? ? ? ? //param:targetSize 即你想要的圖片尺寸,若想要原尺寸則可輸入PHImageManagerMaximumSize

? ? ? ? ? ? [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(WIDTH/4, HEIGHT/4) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {

? ? ? ? ? ? ? ? NSString*types =@"0";? //0:照片 1:視頻

? ? ? ? ? ? ? ? if(asset.mediaType==PHAssetMediaTypeImage)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? types =@"0";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? types =@"1";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? NSDictionary*dic =@{@"image":image,@"type":types,@"times":@"0"};

? ? ? ? ? ? ? ? [imageArrayaddObject:dic];

? ? ? ? ? ? }];

? ? ? ? }


? ? ? ? //初始化是否選擇的數(shù)組

? ? ? ? selectArray= [NSMutableArrayarray];

? ? ? ? for(inti=0;i

? ? ? ? {

? ? ? ? ? ? [selectArrayaddObject:@"0"];

? ? ? ? }

? ? ? ? //通知主線程刷新

? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? //回調(diào)或者說是通知主線程刷新

? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? ? ? [self.viewhideToastActivity];

? ? ? ? });

? ? });

}

7.上滑和下拉操作手勢(shì)實(shí)現(xiàn)方法

- (void)handleSwipeFrom:(UISwipeGestureRecognizer*)recognizer

{

? ? if(recognizer.direction ==UISwipeGestureRecognizerDirectionUp) //上拉

? ? {

? ? ? ? if(!UPorDown)

? ? ? ? {

? ? ? ? ? ? CGFloatyy =toolView.frame.origin.y;

? ? ? ? ? ? if(yy>100)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [UIView animateWithDuration:0.5 animations:^{

? ? ? ? ? ? ? ? ? ? toolView.transform=CGAffineTransformMakeTranslation(0, -yy+kStatusBarHeight);

? ? ? ? ? ? ? ? ? ? bottomV.transform=CGAffineTransformMakeTranslation(0, -yy+kStatusBarHeight);

? ? ? ? ? ? ? ? ? ? myCollectionView.frame=CGRectMake(0,0,WIDTH,HEIGHT-44-kStatusBarHeight);

? ? ? ? ? ? ? ? }completion:^(BOOLfinished){

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? }


? ? ? ? ? ? UPorDown=YES;

? ? ? ? }

? ? }

? ? else if(recognizer.direction ==UISwipeGestureRecognizerDirectionDown)? //下滑

? ? {

? ? ? ? if(UPorDown)

? ? ? ? {

? ? ? ? ? ? if(isTop)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [UIView animateWithDuration:0.5 animations:^{

? ? ? ? ? ? ? ? ? ? toolView.transform = CGAffineTransformMakeTranslation(0, 0);

? ? ? ? ? ? ? ? ? ? bottomV.transform = CGAffineTransformMakeTranslation(0, 0);

? ? ? ? ? ? ? ? }completion:^(BOOLfinished){

? ? ? ? ? ? ? ? ? ? myCollectionView.frame=CGRectMake(0,0,WIDTH,221+kSafeAreaBottomHeight);

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? ? ? UPorDown=NO;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

8.下拉加載下一頁(yè)(200條)的數(shù)據(jù)

-(void)footerClick

{

? ? if(phArray.count<200)

? ? {

? ? ? ? return;

? ? }

? ? ready=NO;

? ? NSIntegercounts =phArray.count;

? ? NSIntegernowCounts =200+page*200;

? ? if(nowCounts < counts)

? ? {

? ? ? ? if(nowCounts < counts -200)

? ? ? ? {

? ? ? ? ? ? counts = nowCounts +200;

? ? ? ? }

? ? }


? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? ? ? // 處理耗時(shí)操作的代碼塊

? ? ? ? for(NSIntegeri=nowCounts;i

? ? ? ? {

? ? ? ? ? ? PHAsset*asset = [phArrayobjectAtIndex:i];

? ? ? ? ? ? PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];

? ? ? ? ? ? /** resizeMode:對(duì)請(qǐng)求的圖像怎樣縮放。有三種選擇:None,默認(rèn)加載方式;Fast,盡快地提供接近或稍微大于要求的尺寸;Exact,精準(zhǔn)提供要求的尺寸。 deliveryMode:圖像質(zhì)量。有三種值:Opportunistic,在速度與質(zhì)量中均衡;HighQualityFormat,不管花費(fèi)多長(zhǎng)時(shí)間,提供高質(zhì)量圖像;FastFormat,以最快速度提供好的質(zhì)量。

?? ? ? ? ? ? 這個(gè)屬性只有在 synchronous 為 true 時(shí)有效。

?? ? ? ? ? ? */

? ? ? ? ? ? option.resizeMode = PHImageRequestOptionsResizeModeFast;//控制照片尺寸

? ? ? ? ? ? option.deliveryMode=1;//控制照片質(zhì)量

? ? ? ? ? ? option.synchronous=YES;

? ? ? ? ? ? option.networkAccessAllowed=YES;

? ? ? ? ? ? //param:targetSize 即你想要的圖片尺寸,若想要原尺寸則可輸入PHImageManagerMaximumSize

? ? ? ? ? ? [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(WIDTH/4, HEIGHT/4) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {

? ? ? ? ? ? ? ? NSString*types =@"0";? //0:照片 1:視頻

? ? ? ? ? ? ? ? if(asset.mediaType==PHAssetMediaTypeImage)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? types =@"0";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? types =@"1";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? NSDictionary*dic =@{@"image":image,@"type":types,@"times":@"0"};

? ? ? ? ? ? ? ? [imageArrayaddObject:dic];

? ? ? ? ? ? ? ? [selectArrayaddObject:@"0"];

? ? ? ? ? ? }];

? ? ? ? }


? ? ? ? //通知主線程刷新

? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? //回調(diào)或者說是通知主線程刷新

? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? ? ? [self.viewhideToastActivity];

? ? ? ? ? ? page++;

? ? ? ? ? ? ready=YES;

? ? ? ? });

? ? });

}

9.手勢(shì)協(xié)議的實(shí)現(xiàn)(防止UICollectionView的滾動(dòng)事件和手勢(shì)沖突)

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer

{

? ? return YES;

}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch

{

? ? if([NSStringFromClass([touch.view class]) isEqualToString:@"UIView"])

? ? {

? ? ? ? UIView*vies = touch.view;

? ? ? ? if(vies.tag==88)

? ? ? ? {

? ? ? ? ? ? isTop=YES;

? ? ? ? }

? ? }

? ? if([NSStringFromClass([touch.view class]) isEqual:@"UICollectionView"])

? ? {

? ? ? ? returnNO;

? ? }

? ? else

? ? {

? ? ? ? returnYES;

? ? }

}

10.滾動(dòng)過程中的監(jiān)聽

- (void)scrollViewDidScroll:(UIScrollView*)scrollView

{

? ? CGPointlocalPoint = scrollView.contentOffset;

? ? if(localPoint.y<=0)

? ? {

? ? ? ? isTop=YES;

? ? }

? ? else

? ? {

? ? ? ? isTop=NO;

? ? ? ? if(localPoint.y>(page+1)*3800)? //還未到達(dá)最底部就開始加載下200條,預(yù)防卡頓

? ? ? ? {

? ? ? ? ? ? if(ready)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [selffooterClick];

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

11.CollectionView協(xié)議方法實(shí)現(xiàn)

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView

{

? ? return1;

}

/**

?設(shè)置CollectionView每組所包含的個(gè)數(shù)

?*/

- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section

{

? ? return imageArray.count;

}

/**

?設(shè)置CollectionCell的內(nèi)容

?*/

- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath

{

? ? HobbiesCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HobbiesCollectionViewCell"forIndexPath:indexPath];

? ? cell.bgImageView.image = [imageArray[indexPath.row] objectForKey:@"image"];

? ? if([[imageArray[indexPath.row] objectForKey:@"type"] isEqualToString:@"0"])? //照片類型,隱藏視頻相關(guān)控件

? ? {

? ? ? ? cell.playImageView.hidden =YES;

? ? ? ? cell.playMengView.hidden =YES;

? ? ? ? cell.playTimeLabel.hidden =YES;

? ? }

? ? else? //視頻類型

? ? {

? ? ? ? cell.playImageView.hidden =NO;

? ? ? ? cell.playMengView.hidden =NO;

? ? ? ? cell.playTimeLabel.hidden =NO;

? ? ? ? if([[imageArray[indexPath.row] objectForKey:@"times"] isEqualToString:@"0"])

? ? ? ? {? //異步獲取視頻時(shí)長(zhǎng)

? ? ? ? ? ? dispatch_async(dispatch_get_global_queue(0,0), ^{

? ? ? ? ? ? ? ? // 處理耗時(shí)操作的代碼塊...

? ? ? ? ? ? ? ? PHAsset *asset = [phArray objectAtIndex:indexPath.row];

? ? ? ? ? ? ? ? __blockintseconds;

? ? ? ? ? ? ? ? [[TZImageManager manager] getVideoWithAsset:asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {

? ? ? ? ? ? ? ? ? ? AVAsset *avasset = playerItem.asset;

? ? ? ? ? ? ? ? ? ? AVURLAsset *urlAsset = (AVURLAsset *)avasset;

? ? ? ? ? ? ? ? ? ? CMTime time = [urlAsset duration];

? ? ? ? ? ? ? ? ? ? seconds = (int)time.value/time.timescale;

? ? ? ? ? ? ? ? ? ? NSDictionary *dic =@{@"image":[imageArray[indexPath.row] objectForKey:@"image"],@"type":[imageArray[indexPath.row] objectForKey:@"type"],@"times":[NSString stringWithFormat:@"%d",seconds]};

? ? ? ? ? ? ? ? ? ? [imageArray replaceObjectAtIndex:indexPath.row withObject:dic];

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? ? ? //通知主線程刷新

? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? ? ? [myCollectionView reloadData];

? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? });

? ? ? ? ? ? });

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? cell.playTimeLabel.text = [selftimeEdit:[NSString stringWithFormat:@"%@",[imageArray[indexPath.row] objectForKey:@"times"]]];

? ? ? ? }

? ? }


? ? //處理選擇后的顯示

? ? if([selectArray[indexPath.row] isEqualToString:@"0"])

? ? {

? ? ? ? cell.selectImageView.backgroundColor = [UIColor clearColor];

? ? ? ? cell.cellNumLabel.text =@"";

? ? ? ? cell.selectImageView.image = [UIImage imageNamed:@"noSelect"];

? ? }

? ? else

? ? {

? ? ? ? cell.selectImageView.backgroundColor = [UIColor colorWithRed:(255)/255.0green:(175)/255.0blue:(33)/255.0alpha:1.0];

? ? ? ? cell.selectImageView.image =nil;

? ? ? ? cell.cellNumLabel.text = selectArray[indexPath.row];

? ? }

? ? cell.selectImageView.hidden =NO;

? ? cell.selectBtn.tag = indexPath.row;

? ? [cell.selectBtn addTarget:selfaction:@selector(selectBtnClicked:) forControlEvents:UIControlEventTouchUpInside];


? ? returncell;

}

/**

?定義每個(gè)UICollectionView的大小

?*/

- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath

{

? ? return? CGSizeMake(WIDTH/4-1,WIDTH/4-1);

}

/**

?定義整個(gè)CollectionViewCell與整個(gè)View的間距

?*/

- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section

{

? ? return UIEdgeInsetsMake(1, 1, 1, 1);//(上、左、下、右)

}

/**

?定義每個(gè)UICollectionView的橫向間距

?*/

- (CGFloat)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section

{

? ? return0;

}

/**

?定義每個(gè)UICollectionView的縱向間距

?*/

- (CGFloat)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

{

? ? return0;

}

/**

?點(diǎn)擊CollectionView觸發(fā)事件

?*/

-(void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath

{

? ? if([[imageArray[indexPath.row]objectForKey:@"type"]isEqualToString:@"0"])//照片

? ? {

? ? ? ? [selflookImage:indexPath.row];

? ? }

? ? else

? ? {

? ? ? ? [selflookVideo:indexPath.row];

? ? }

}

/**

?設(shè)置CollectionViewCell是否可以被點(diǎn)擊

?*/

- (BOOL)collectionView:(UICollectionView*)collectionView shouldSelectItemAtIndexPath:(NSIndexPath*)indexPath

{

? ? return YES;

}

12.時(shí)間格式處理

-(NSString*)timeEdit:(NSString*)times

{

? ? inttimeNum = [timesintValue];

? ? if(timeNum<10)

? ? {

? ? ? ? return[NSStringstringWithFormat:@"00:0%d",timeNum];

? ? }

? ? elseif(timeNum<60)

? ? {

? ? ? ? return[NSStringstringWithFormat:@"00:%d",timeNum];

? ? }

? ? else

? ? {

? ? ? ? inta = timeNum%60;

? ? ? ? intb = timeNum/60;

? ? ? ? if(a<10)

? ? ? ? {

? ? ? ? ? ? if(b<10)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return[NSStringstringWithFormat:@"0%d:0%d",b,a];

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return[NSStringstringWithFormat:@"%d:0%d",b,a];

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? if(b<10)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return[NSStringstringWithFormat:@"0%d:%d",b,a];

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return[NSStringstringWithFormat:@"%d:%d",b,a];

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

13.查看圖片

-(void)lookImage:(NSInteger)currentIndex

{

? ? YBImageBrowser *browser = [YBImageBrowser new];

? ? browser.dataSource=self;

? ? browser.currentIndex= currentIndex;

? ? //展示

? ? [browsershow];

}

14.查看視頻(單獨(dú)寫了一個(gè)查看視頻文件,詳情請(qǐng)看下方git鏈接)

-(void)lookVideo:(NSInteger)currentIndex

{

? ? PHAsset*phAsset =phArray[currentIndex];

? ? if(phAsset.mediaType==PHAssetMediaTypeVideo) {

? ? ? ? PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];

? ? ? ? options.version = PHImageRequestOptionsVersionCurrent;

? ? ? ? options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;

? ? ? ? PHImageManager *manager = [PHImageManager defaultManager];

? ? ? ? [managerrequestAVAssetForVideo:phAssetoptions:optionsresultHandler:^(AVAsset*_Nullableasset,AVAudioMix*_NullableaudioMix,NSDictionary*_Nullableinfo) {

? ? ? ? ? ? AVURLAsset*urlAsset = (AVURLAsset*)asset;

? ? ? ? ? ? NSURL*url = urlAsset.URL;

? ? ? ? ? ? NSString*urls = [NSStringstringWithFormat:@"%@",url];

? ? ? ? ? ? VideoPlayViewController *playVC = [[VideoPlayViewController alloc] init];

? ? ? ? ? ? playVC.url= urls;

? ? ? ? ? ? [self presentViewController:playVC? animated:YES completion:nil];

? ? ? ? }];

? ? }

}

15.選擇視頻或照片實(shí)現(xiàn)

-(void)selectBtnClicked:(UIButton*)sender

{

? ? if(nums==0)

? ? {

? ? ? ? IorV= -1;

? ? }

? ? if([[imageArray[sender.tag] objectForKey:@"type"] isEqualToString:@"0"]) //照片

? ? {

? ? ? ? if(IorV==1)

? ? ? ? {

? ? ? ? ? ? [self.viewmakeToast:@"視頻和照片只能上傳一種!"duration:2position:CENTER];

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? IorV=0;

? ? ? ? if([selectArray[sender.tag]isEqualToString:@"0"])

? ? ? ? {

? ? ? ? ? ? if(nums==9)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [self.viewmakeToast:@"最多只能選擇9張照片!"duration:2position:CENTER];

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? nums++;

? ? ? ? ? ? [selectArray replaceObjectAtIndex:sender.tag withObject:[NSString stringWithFormat:@"%ld",(long)nums]];

? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? if([selectArray[sender.tag]integerValue] ==9)//是最后一個(gè)只要刷新最后一條的數(shù)據(jù)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [selectArrayreplaceObjectAtIndex:sender.tagwithObject:@"0"];

? ? ? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {


? ? ? ? ? ? ? ? for(inti=0;i

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? NSIntegerindexs = [selectArray[i]integerValue];

? ? ? ? ? ? ? ? ? ? if(indexs>[selectArray[sender.tag]integerValue])

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? [selectArray replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%ld",(long)indexs]];

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? [selectArrayreplaceObjectAtIndex:sender.tagwithObject:@"0"];

? ? ? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? ? ? }

? ? ? ? ? ? nums--;

? ? ? ? }

? ? }

? ? else

? ? {

? ? ? ? if(IorV==0)

? ? ? ? {

? ? ? ? ? ? [self.viewmakeToast:@"視頻和照片只能上傳一種!"duration:2position:CENTER];

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? IorV=1;

? ? ? ? if([selectArray[sender.tag]isEqualToString:@"0"])

? ? ? ? {

? ? ? ? ? ? if(nums==1)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? [self.viewmakeToast:@"最多只能選擇1個(gè)視頻!"duration:2position:CENTER];

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? nums++;

? ? ? ? ? ? [selectArray replaceObjectAtIndex:sender.tag withObject:[NSString stringWithFormat:@"%ld",(long)nums]];

? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? [selectArray replaceObjectAtIndex:sender.tag withObject:@"0"];

? ? ? ? ? ? [myCollectionViewreloadData];

? ? ? ? ? ? nums-- ;

? ? ? ? }

? ? }

}

16.YBImageBrowserDataSource 代理實(shí)現(xiàn)賦值數(shù)據(jù)(圖片查看)

- (NSUInteger)yb_numberOfCellForImageBrowserView:(YBImageBrowserView*)imageBrowserView {

? ? returnphArray.count;

}

- (id)yb_imageBrowserView:(YBImageBrowserView*)imageBrowserView dataForCellAtIndex:(NSUInteger)index {

? ? YBImageBrowseCellData *data = [YBImageBrowseCellData new];

? ? data.phAsset=phArray[index];

? ? returndata;

}


備注:目前根據(jù)項(xiàng)目,最多只能選擇9張圖片,并且圖片和視頻只能選擇一種,所以做了限制。選擇完成后,循環(huán)遍歷selectArray既可獲得所選的文件數(shù)據(jù),代碼大致如下:

{

? ? imageUrlArray = [NSMutableArray array];

? ? NSMutableArray *postImgArray = [NSMutableArray array];

? ? for(inti=0;i

? ? {

? ? ? ? if(![selectArray[i] isEqualToString:@"0"])

? ? ? ? {

? ? ? ? ? ? PHAsset *asset = phArray[i];

? ? ? ? ? ? if(IorV==1)? //視頻

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //視頻只能選擇一個(gè),直接這里轉(zhuǎn)視頻,然后上傳

? ? ? ? ? ? ? ? if(asset.mediaType == PHAssetMediaTypeVideo)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? [[TZImageManager manager] getVideoWithAsset:asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {

? ? ? ? ? ? ? ? ? ? ? ? AVAsset *avasset = playerItem.asset;

? ? ? ? ? ? ? ? ? ? ? ? AVURLAsset *urlAsset = (AVURLAsset *)avasset;

? ? ? ? ? ? ? ? ? ? ? ? NSURL *urls = urlAsset.URL;

? ? ? ? ? ? ? ? ? ? ? ? CMTime time = [urlAsset duration];

? ? ? ? ? ? ? ? ? ? ? ? intseconds = ceil(time.value/time.timescale);

? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"視頻時(shí)長(zhǎng):%d",seconds);


? ? ? ? ? ? ? ? ? ? ? ? NSData *data = [NSData dataWithContentsOfURL:urls];

? ? ? ? ? ? ? ? ? ? ? ? NSInteger videoSize = data.length/1024;

? ? ? ? ? ? ? ? ? ? ? ? floatsizes = (float)videoSize/1024;

? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"視頻大?。?.2f M",sizes);

? ? ? ? ? ? ? ? ? ? ? ? /*

?? ? ? ? ? ? ? ? ? ? ? ? 創(chuàng)建AVAssetExportSession對(duì)象

?? ? ? ? ? ? ? ? ? ? ? ? 壓縮的質(zhì)量

?? ? ? ? ? ? ? ? ? ? ? ? AVAssetExportPresetLowQuality 最low的畫質(zhì)最好不要選擇實(shí)在是看不清楚

?? ? ? ? ? ? ? ? ? ? ? ? AVAssetExportPresetMediumQuality 使用到壓縮的話都說用這個(gè)

?? ? ? ? ? ? ? ? ? ? ? ? AVAssetExportPresetHighestQuality 最清晰的畫質(zhì)

?? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? ? ? ? ? AVAssetExportSession * session = [[AVAssetExportSession alloc] initWithAsset:avasset presetName:AVAssetExportPreset960x540];

? ? ? ? ? ? ? ? ? ? ? ? //優(yōu)化網(wǎng)絡(luò)

? ? ? ? ? ? ? ? ? ? ? ? session.shouldOptimizeForNetworkUse =YES;

? ? ? ? ? ? ? ? ? ? ? ? //轉(zhuǎn)換后的格式

? ? ? ? ? ? ? ? ? ? ? ? //拼接輸出文件路徑 為了防止同名 可以根據(jù)日期拼接名字 或者對(duì)名字進(jìn)行MD5加密

? ? ? ? ? ? ? ? ? ? ? ? NSString* path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent:@"hello.mp4"];

? ? ? ? ? ? ? ? ? ? ? ? //判斷文件是否存在,如果已經(jīng)存在刪除

? ? ? ? ? ? ? ? ? ? ? ? [[NSFileManager defaultManager]removeItemAtPath:path error:nil];

? ? ? ? ? ? ? ? ? ? ? ? //設(shè)置輸出路徑

? ? ? ? ? ? ? ? ? ? ? ? session.outputURL = [NSURL fileURLWithPath:path];

? ? ? ? ? ? ? ? ? ? ? ? //設(shè)置輸出類型 這里可以更改輸出的類型 具體可以看文檔描述

? ? ? ? ? ? ? ? ? ? ? ? session.outputFileType = AVFileTypeMPEG4;

? ? ? ? ? ? ? ? ? ? ? ? session.videoComposition = [selfgetVideoComposition:urlAsset];

? ? ? ? ? ? ? ? ? ? ? ? [session exportAsynchronouslyWithCompletionHandler:^{

? ? ? ? ? ? ? ? ? ? ? ? ? ? //壓縮完成

? ? ? ? ? ? ? ? ? ? ? ? ? ? if(session.status==AVAssetExportSessionStatusCompleted) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //在主線程中刷新UI界面,彈出控制器通知用戶壓縮完成

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"導(dǎo)出完成");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSURL *beforeurl = session.outputURL;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSData *datass = [NSData dataWithContentsOfURL:beforeurl];

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSInteger videoSizess = datass.length/1024;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? floatsizess = (float)videoSizess/1024;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"壓縮完畢,壓縮后大小 %.2f MB",sizess);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //去上傳視頻,地址為beforeurl

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }];

? ? ? ? ? ? ? ? ? ? }];

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //照片可以傳多張,所以循環(huán)添加進(jìn)postImgArray

? ? ? ? ? ? ? ? PHImageManager *manager = [PHImageManager defaultManager];

? ? ? ? ? ? ? ? PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];

? ? ? ? ? ? ? ? /** resizeMode:對(duì)請(qǐng)求的圖像怎樣縮放。有三種選擇:None,默認(rèn)加載方式;Fast,盡快地提供接近或稍微大于要求的尺寸;Exact,精準(zhǔn)提供要求的尺寸。 deliveryMode:圖像質(zhì)量。有三種值:Opportunistic,在速度與質(zhì)量中均衡;HighQualityFormat,不管花費(fèi)多長(zhǎng)時(shí)間,提供高質(zhì)量圖像;FastFormat,以最快速度提供好的質(zhì)量。

?? ? ? ? ? ? ? ? 這個(gè)屬性只有在 synchronous 為 true 時(shí)有效。

?? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? option.resizeMode = PHImageRequestOptionsResizeModeFast;//控制照片尺寸

? ? ? ? ? ? ? ? option.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;//控制照片質(zhì)量

? ? ? ? ? ? ? ? option.synchronous =YES;

? ? ? ? ? ? ? ? option.networkAccessAllowed =YES;

? ? ? ? ? ? ? ? [manager requestImageForAsset:phArray[i] targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:option resultHandler:^(UIImage *resultImage, NSDictionary *info)

?? ? ? ? ? ? ? ? {

?? ? ? ? ? ? ? ? ? ? [postImgArray addObject:resultImage];

?? ? ? ? ? ? ? ? ? ? if(postImgArray.count == nums)

?? ? ? ? ? ? ? ? ? ? {

?? ? ? ? ? ? ? ? ? ? ? ? //當(dāng)postImgArray的數(shù)量和開始記錄的選中數(shù)量相等的時(shí)候,開始上傳操作

?? ? ? ? ? ? ? ? ? ? }

?? ? ? ? ? ? ? ? }];

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

大致思路是如此,第一次寫簡(jiǎn)書,比較亂,大家勿怪,下方貼上github鏈接,可以下載下來看demo參考,順便給個(gè)star,感謝??。祝大家生活愉快,永不脫發(fā)。

GitHub鏈接:https://github.com/bingegegege/photosPicker.git

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容