? ? 項(xiàng)目中需要用到相冊(cè)又跛,自己封裝比較耗時(shí),所以選擇了現(xiàn)成的第三方SDK笋庄,選來選去(其實(shí)也沒怎么選)最終選擇了TZImagePickerController(以下簡(jiǎn)稱TZImage)。很舒服的一個(gè)開源相冊(cè)倔监,功能還是很強(qiáng)大直砂,在此膜拜一下作者。
? ? 那么說一說我在使用時(shí)遇到的一個(gè)小問題浩习,如題:
? ? bug:當(dāng)系統(tǒng)相冊(cè)中出現(xiàn)“來自未來的照片”(相冊(cè)中有照片的存儲(chǔ)時(shí)間是未來的某個(gè)時(shí)間静暂,原因暫時(shí)未知,可能是用戶在拍照時(shí)自行修改了iPhone的時(shí)間)谱秽,使用TZImage的拍照功能會(huì)出現(xiàn)最終得到的照片不是拍照獲得的照片問題洽蛀。(有點(diǎn)拗口,應(yīng)該能理解吧)
? ? 問題原因(想看解決方法的同學(xué)們可以跳過):TZImage拍照完成之后疟赊,會(huì)將照片按照當(dāng)前拍攝時(shí)間存入本地相冊(cè)郊供,然后更新相冊(cè),再?gòu)南鄡?cè)中取出當(dāng)前排序的第一張照片返回給我們近哟。而一般來說驮审,相冊(cè)的排序都是按照時(shí)間來排的,不論你是選擇正序還是倒序吉执,所以在正常情況下這樣做是毫無問題的疯淫。但就是有時(shí)候是不正常的。就像我上面描述所說的:系統(tǒng)相冊(cè)中出現(xiàn)來自未來的照片戳玫,這種情況下熙掺,TZImage拍照后獲得的照片永遠(yuǎn)都是相冊(cè)中的第一張照片。然而我們拍攝得到的照片是當(dāng)前時(shí)間咕宿,肯定不會(huì)被放在相冊(cè)的第一張了币绩,也就出現(xiàn)了所拍不所得的問題蜡秽。(很尷尬)
? ? 既然發(fā)現(xiàn)的問題的原因,那么解決起來就方便多了类浪。先來說說我的思路载城,其實(shí)這個(gè)問題不算很難解決,我能想到3種解決方法费就。(原諒我這個(gè)菜雞就這點(diǎn)水平)
? ? 1诉瓦、在TZImage拍攝完照片的代理中取到當(dāng)前拍攝的照片,使用block或者代理傳遞到我們需要的地方力细,跳過存儲(chǔ)和更新相冊(cè)的過程睬澡。
? ? 這種方案簡(jiǎn)單暴力,解決起來應(yīng)該是最快的方式眠蚂∩反希可是對(duì)于后續(xù)的需求就會(huì)造成不便,我們知道在相機(jī)的回調(diào)中通過此方法獲得的照片是原圖
所以對(duì)于一些諸如頭像設(shè)置之類的不需要圖片質(zhì)量那么大的情況下逝慧,原圖會(huì)造成一些不必要的流量操作昔脯,網(wǎng)絡(luò)不好的話用戶體驗(yàn)也會(huì)受到一定影響。當(dāng)然我們可以在這里就對(duì)圖片進(jìn)行壓縮處理笛臣,但是這種處理方式顯然不是最好的云稚。
? ? 2、在TZImage存儲(chǔ)照片的時(shí)候沈堡,對(duì)存儲(chǔ)的時(shí)間進(jìn)行調(diào)整静陈。
? ? 這種處理方式也很簡(jiǎn)單,而且無需更多的操作诞丽,只是簡(jiǎn)單的修改一下照片的時(shí)間屬性鲸拥。
只需要在這里將[NSDate date]改成一個(gè)相對(duì)靠后的時(shí)間,你不是來自未來的照片嗎僧免,我讓你知道什么是未來刑赶,設(shè)置一個(gè)2100年,什么懂衩?還不夠角撞。那就2200年,總之我就是要我拍攝的照片放在相冊(cè)的第一個(gè)勃痴,怎么說谒所?
皮一下很舒服。好了沛申,言歸正傳劣领,這種處理方式顯然也是有問題的,到時(shí)候因?yàn)橐粋€(gè)APP導(dǎo)致手機(jī)里一堆搞不清楚時(shí)間的照片铁材,就皮不起來了尖淘。
? ? 3奕锌、也是我目前能想到的最好的解決方式。當(dāng)照片存儲(chǔ)完成之后村生,通過照片的localIdentifier獲取到照片的PHAsset(iOS 8之前獲取ALAsset)惊暴,再通過PHAsset/ALAsset,獲取到TZAssetModel(TZImage自己的圖片對(duì)象)趁桃,接著在更新相冊(cè)的方法中辽话,把我們剛才獲取到的Model傳進(jìn)來(推薦block),不再使用TZImage原先的方式取值卫病,把我們自己獲取到的Model存入回調(diào)數(shù)組中油啤,萬事大吉。
? ? 說起來很抽象蟀苛?上代碼:
我將TZImage的savePhotoWithImage:location:completion方法的block進(jìn)行了調(diào)整益咬,新增了一個(gè)返回值TZAssetModel *assetModel。在savePhotoWithImage:location:completion方法中將其獲取并傳遞回來:
- (void)savePhotoWithImage:(UIImage*)image location:(CLLocation*)location completion:(getCurrentPhotos)completion {
? ? __blockTZAssetModel*model =nil;
? ? __blockNSString*idStr =nil;
? ? if (iOS8Later) {
? ? ? ? [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
? ? ? ? ? ? if(iOS9Later) {
? ? ? ? ? ? ? ? NSData*data =UIImageJPEGRepresentation(image,0.9);
? ? ? ? ? ? ? ? PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
? ? ? ? ? ? ? ? options.shouldMoveFile=YES;
? ? ? ? ? ? ? ? PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
? ? ? ? ? ? ? ? [requestaddResourceWithType:PHAssetResourceTypePhoto data:data options:options];
? ? ? ? ? ? ? ? if(location) {
? ? ? ? ? ? ? ? ? ? request.location= location;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? request.creationDate= [NSDatedate];
? ? ? ? ? ? ? ? idStr = request.placeholderForCreatedAsset.localIdentifier;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
? ? ? ? ? ? ? ? if(location) {
? ? ? ? ? ? ? ? ? ? request.location= location;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? request.creationDate= [NSDatedate];
? ? ? ? ? ? ? ? idStr = request.placeholderForCreatedAsset.localIdentifier;
? ? ? ? ? ? }
? ? ? ? }completionHandler:^(BOOLsuccess,NSError*error) {
? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? if(success && completion) {
? ? ? ? ? ? ? ? ? ? PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[idStr] options:nil];
? ? ? ? ? ? ? ? ? ? if(result) {
? ? ? ? ? ? ? ? ? ? ? ? PHAsset*asset = [resultlastObject];
? ? ? ? ? ? ? ? ? ? ? ? model = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypePhoto];
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? completion(model,nil);
? ? ? ? ? ? ? ? }elseif(error) {
? ? ? ? ? ? ? ? ? ? NSLog(@"保存照片出錯(cuò):%@",error.localizedDescription);
? ? ? ? ? ? ? ? ? ? if(completion) {
? ? ? ? ? ? ? ? ? ? ? ? completion(model, error);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }];
? ? }else{
? ? ? ? [self.assetLibrary writeImageToSavedPhotosAlbum:image.CGImage orientation:[self orientationFromImage:image] completionBlock:^(NSURL *assetURL, NSError *error) {
? ? ? ? ? ? if(error) {
? ? ? ? ? ? ? ? NSLog(@"保存圖片失敗:%@",error.localizedDescription);
? ? ? ? ? ? ? ? if(completion) {
? ? ? ? ? ? ? ? ? ? completion(model, error);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? // 多給系統(tǒng)0.5秒的時(shí)間帜平,讓系統(tǒng)去更新相冊(cè)數(shù)據(jù)
? ? ? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? ? ? if(completion) {
? ? ? ? ? ? ? ? ? ? ? ? [self.assetLibraryassetForURL:assetURLresultBlock:^(ALAsset*asset) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? model = [TZAssetModel modelWithAsset:assetURL type:TZAssetModelMediaTypePhoto];
? ? ? ? ? ? ? ? ? ? ? ? ? ? completion(model,nil);
? ? ? ? ? ? ? ? ? ? ? ? }failureBlock:^(NSError*error) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? completion(model,nil);
? ? ? ? ? ? ? ? ? ? ? ? }];
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? }
? ? ? ? }];
? ? }
}
最后幽告,修改排序的方法:
- (void)reloadPhotoArray:(TZAssetModel*)currentAssetModel {
? ? TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
? ? [[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
? ? ? ? _model= model;
? ? ? ? [[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray *models) {
? ? ? ? ? ? [tzImagePickerVchideProgressHUD];
? ? ? ? ? ? TZAssetModel*assetModel = currentAssetModel;
? ? ? ? ? ? if(tzImagePickerVc.sortAscendingByModificationDate) {
//? ? ? ? ? ? ? ? assetModel = [models lastObject];
? ? ? ? ? ? ? ? [_modelsaddObject:assetModel];
? ? ? ? ? ? }else{
//? ? ? ? ? ? ? ? assetModel = [models firstObject];
? ? ? ? ? ? ? ? [_modelsinsertObject:assetModelatIndex:0];
? ? ? ? ? ? }
? ? ? ? ? ? if(tzImagePickerVc.maxImagesCount<=1) {
? ? ? ? ? ? ? ? if(tzImagePickerVc.allowCrop) {
? ? ? ? ? ? ? ? ? ? TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
//? ? ? ? ? ? ? ? ? ? if (tzImagePickerVc.sortAscendingByModificationDate) {
//? ? ? ? ? ? ? ? ? ? ? ? photoPreviewVc.currentIndex = _models.count - 1;
//? ? ? ? ? ? ? ? ? ? } else {
//? ? ? ? ? ? ? ? ? ? ? ? photoPreviewVc.currentIndex = 0;
//? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? photoPreviewVc.currentIndex= [_modelsindexOfObject:assetModel];
? ? ? ? ? ? ? ? ? ? photoPreviewVc.models=_models;
? ? ? ? ? ? ? ? ? ? [selfpushPhotoPrevireViewController:photoPreviewVc];
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? [tzImagePickerVc.selectedModelsaddObject:assetModel];
? ? ? ? ? ? ? ? ? ? [selfdoneButtonClick];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? if(tzImagePickerVc.selectedModels.count< tzImagePickerVc.maxImagesCount) {
? ? ? ? ? ? ? ? assetModel.isSelected=YES;
? ? ? ? ? ? ? ? [tzImagePickerVc.selectedModelsaddObject:assetModel];
? ? ? ? ? ? ? ? [self refreshBottomToolBarStatus];
? ? ? ? ? ? }
? ? ? ? ? ? _collectionView.hidden=YES;
? ? ? ? ? ? [_collectionViewreloadData];
? ? ? ? ? ? _shouldScrollToBottom = YES;
? ? ? ? ? ? [self scrollCollectionViewToBottom];
? ? ? ? }];
? ? }];
}
原諒我把注釋掉的代碼也貼上來了,主要是方便以后我查看自己修改的部分裆甩。
PS:第一次寫簡(jiǎn)書冗锁。而且技術(shù)有限,只能分享一下自己解決問題的思路和最后的成果淑掌。大佬們?nèi)舭l(fā)現(xiàn)什么問題蒿讥,請(qǐng)多多指正蝶念,我需要你們的鞭策抛腕。鞭。媒殉。担敌。。策(哪里怪怪的)