前言
經(jīng)過(guò)幾天的斷斷續(xù)續(xù)的編寫終于把這一個(gè)小項(xiàng)目完成了广匙,現(xiàn)在剛剛完成,代碼看著不整潔恼策,請(qǐng)多包涵鸦致。前幾天要弄個(gè)相冊(cè)多選和照相選圖的功能,以前做過(guò)單選上傳頭像之類的涣楷。但是多選確實(shí)不像那么簡(jiǎn)單分唾,github找了好多的例子,都是在用幾個(gè)框架狮斗。不是說(shuō)人家封的不好绽乔,封的很好,但是鹵煮比較笨碳褒,看了好久還是馬馬虎虎折砸。然后上網(wǎng)查了下資料,還是決定自己寫一個(gè)沙峻。
正文
多選主要是需要一個(gè)frameworks:AssetsLibrary。這個(gè)類的主要功能就是多選(個(gè)人理解摔寨,不對(duì)請(qǐng)見(jiàn)諒)去枷。
首先,我們從相冊(cè)開(kāi)始:要查看所有的相冊(cè)是复,簡(jiǎn)單的思路大家應(yīng)該都有:獲取相冊(cè)組---獲取相冊(cè)删顶,但是怎么進(jìn)行呢,AssetsLibrary的用處來(lái)了淑廊。
- (void)countOfAlbumGroup:(void(^)(ALAssetsGroup *yfGroup))block{ //計(jì)算有幾個(gè)相冊(cè)
[self enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
if (block) {
block(group);
}
}
} failureBlock:^(NSError *error) {
NSLog(@"獲取相冊(cè)錯(cuò)誤,%@",error); }];
}
這個(gè)是計(jì)算相冊(cè)數(shù)逗余,可能手機(jī)相冊(cè)會(huì)有好幾個(gè),所以要查看一下有幾個(gè)季惩,畢竟用戶有很大的可能只會(huì)選擇某一個(gè)相冊(cè)里面的某一張相片猎荠。我是把這個(gè)方法拿了出來(lái)專門創(chuàng)建了一個(gè)類坚弱,這樣代碼思路會(huì)清晰一些。既然我們知道有幾個(gè)相冊(cè)了关摇,每個(gè)相冊(cè)的一些信息也知道了荒叶,那么我們應(yīng)該去顯示某一個(gè)相冊(cè)里面的所有照片了呀。這一步的代碼來(lái)了:
/** * 獲得一個(gè)相冊(cè)有多少照片 * */
- (void)callAllPhoto:(ALAssetsGroup *)group result:(void(^)(YFSelfImage *image))block{ //獲得所有的圖片資源
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result) {
YFSelfImage *image = [[YFSelfImage alloc]initWithCGImage:[result thumbnail]]; image.asset = result;
block(image);
} }];}
這個(gè)方法的一個(gè)參數(shù)group输虱,就是上一個(gè)代碼段得到的相冊(cè)group些楣,拿到group之后就去求里面所有的照片。這里涉及到兩個(gè)點(diǎn)我說(shuō)一下:### YFSelfImage這是一個(gè)我自己稍微封裝了uiimage的一個(gè)類
/** * 用于儲(chǔ)存相冊(cè)圖片宪睹,附有一個(gè)asset信息愁茁,用于圖片的其他處理 * */#import#import@interface YFSelfImage : UIImage
//可能需要的圖片信息
@property(nonatomic,strong)ALAsset *asset;
@end
比普通的UIImage多了一個(gè)屬性,asset亭病。這一個(gè)就是要說(shuō)的第二個(gè)點(diǎn)鹅很。
ALAsset
這一個(gè)類應(yīng)該是多選里面最關(guān)聯(lián)的一個(gè)類了,它有照片的信息關(guān)聯(lián)罪帖,比如縮略圖之類的都可以通過(guò)它獲取促煮。所以,我們多選全靠它去做事情整袁。(關(guān)于用法和屬性菠齿,請(qǐng)google吧,網(wǎng)上有很多很多)坐昙。
好了绳匀,現(xiàn)在相冊(cè)里面的照片也獲取了,我要把它都顯示出來(lái)了炸客,哎呀呀呀呀疾棵,龜派氣功波~~~~~~
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
YFShowAlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:SHOWCELL forIndexPath:indexPath];
YFSelfImage *image = [_dataArray objectAtIndex:indexPath.row];
cell.imageView.image = image;
return cell;
}
然后我們可以查看效果了:
相冊(cè)組:
相冊(cè):
好了,基本的顯示完成了痹仙,大家也看到了陋桂,我上面有個(gè)完成按鈕。那么我們是不是需要在照片那來(lái)個(gè)選擇按鈕蝶溶,然后我們得到選擇的圖片是吧嗜历,不然只是實(shí)現(xiàn)查看相冊(cè)有什么卵用。
再次編輯collectionview:
YFShowAlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:SHOWCELL forIndexPath:indexPath];
cell.selectBtn.tag = cellIndex;
//按鈕選中塊
__weak typeof(self)weakSelf = self;
cell.selectedBlock = ^(NSInteger index){
//把選中的圖片放倒一個(gè)數(shù)組里面
[weakSelf.selectedArray addObject:[weakSelf.dataArray objectAtIndex:index]];
selectBtn.userInteractionEnabled = YES;
};
//取消選定
cell.cancelBlock = ^(NSInteger index){
//找出取消的cell
YFSelfImage *oldImage = [weakSelf.dataArray objectAtIndex:index];
//從選中的數(shù)組去除
for (YFSelfImage *newImage in weakSelf.selectedArray) {
if (newImage == oldImage) {
//移除
[weakSelf.selectedArray removeObject:newImage];
//判斷完成按鈕是否可以使用
if(weakSelf.selectedArray.count <= 0){
selectBtn.userInteractionEnabled = NO;
}
return ;
}
}
};
YFSelfImage *image = [_dataArray objectAtIndex:cellIndex];
cell.imageView.image = image;
return cell;
}
再來(lái)看一下效果:
好了抖所,現(xiàn)在我們是可以選擇了梨州,現(xiàn)在我們要實(shí)現(xiàn)的是把我們選擇的照片拿到放到一個(gè)數(shù)組里面保存使用。前段代碼大家應(yīng)該看見(jiàn)了田轧,照片按鈕的選中與取選操作都謝了暴匠,我們現(xiàn)在完成“完成”這個(gè)按鈕操作了:
/**
* 完成選定
*/
- (void)successChoose{
//把選擇的圖片傳送過(guò)去
NSDictionary *dic = @{@"cellImage":self.selectedArray};
[[NSNotificationCenter defaultCenter]postNotificationName:@"pushImage" object:nil userInfo:dic];
//退出模態(tài)
[self dismissViewControllerAnimated:YES completion:^{
//這一步確保退出到顯示界面的時(shí)候顯示相冊(cè)組控制器一定退出
[self.navigationController popViewControllerAnimated:YES];
}];
}
這個(gè)有個(gè)解釋點(diǎn):
就是數(shù)退出模態(tài)后又做了一次導(dǎo)航pop。因?yàn)檫@個(gè)項(xiàng)目的界面布局是:
所以傻粘,我從單相冊(cè)顯示界面dismiss相當(dāng)于直接回到開(kāi)始界面每窖,但是你在下一次在進(jìn)入相冊(cè)組界面的時(shí)候會(huì)出問(wèn)題帮掉,它會(huì)直接進(jìn)入單相冊(cè)顯示界面,也就是說(shuō)在你dismiss之后后者兩個(gè)界面貌似沒(méi)有釋放的樣子窒典,還是記住了相冊(cè)組界面push到單相冊(cè)界面的狀態(tài)蟆炊。所以我在此處做了一個(gè)pop,防止出現(xiàn)這個(gè)問(wèn)題瀑志。
在完成按鈕時(shí)涩搓,我已經(jīng)選擇了通過(guò)通知把數(shù)組帶回了開(kāi)始界面。所以開(kāi)始界面會(huì)有我們所選擇的照片的顯示劈猪。
這里說(shuō)一下昧甘,這個(gè)刪除事件我就不講了,大家一看應(yīng)該都懂的战得。略過(guò)~~~~~~
好了充边,現(xiàn)在開(kāi)始相機(jī)選擇照片這一塊:
首先我們打開(kāi)一下相冊(cè),固定死代碼:
/**
* 打開(kāi)相機(jī)
*/
- (void)showCamera{
//選擇相機(jī)
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
UIImagePickerController *picker = [[UIImagePickerController alloc] init];//初始化
picker.delegate = self;
// picker.allowsEditing = YES;//設(shè)置可編輯
picker.sourceType = sourceType;
//進(jìn)入照相界面
[[self getCurrentVC] presentViewController:picker animated:YES completion:nil];
}
然后嘞常侦,嘎嘎浇冰,照了照片之后,我們選擇這張照片刮吧,那么學(xué)問(wèn)來(lái)了,我們選擇這張照片可以直接去
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{}
這個(gè)代理里面去做操作掖蛤,當(dāng)然為了和相冊(cè)多選照片的屬性一致杀捻,我們需要做點(diǎn)操作。首先思路應(yīng)該是把照的照片先放到相冊(cè)蚓庭,然后我們?nèi)ハ鄡?cè)去拿到這個(gè)相冊(cè)最后一張圖片致讥,就是這個(gè)相機(jī)照的圖片。
多說(shuō)無(wú)益器赞,上代碼:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{
// //圖片
UIImage *image;
//判斷是不是從相機(jī)過(guò)來(lái)的
if (picker.sourceType != UIImagePickerControllerSourceTypePhotoLibrary) {
//關(guān)閉相機(jī)
[picker dismissViewControllerAnimated:YES completion:nil];
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
//通過(guò)判斷picker的sourceType垢袱,如果是拍照則保存到相冊(cè)去.非常重要的一步,不然港柜,無(wú)法獲取照相的圖片
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
}
/**
* 確定相機(jī)圖片保存到系統(tǒng)相冊(cè)后请契,進(jìn)行圖片獲取
*/
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSLog(@"已保存");
//操作獲得的照片,我這是直接顯示夏醉,你那個(gè)你加到你顯示的一組里面去顯示去就好了
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
//操作獲得的照片爽锥,我這是直接顯示,你那個(gè)你加到你顯示的一組里面去顯示去就好了
[library afterCameraAsset:^(ALAsset *asset) {
YFSelfImage *image = [[YFSelfImage alloc]initWithCGImage:asset.thumbnail];
image.asset = asset;
//傳遞
NSDictionary *dic = @{@"saveImage":image};
[[NSNotificationCenter defaultCenter]postNotificationName:@"SAVEIMAGE" object:nil userInfo:dic];
}];
}
好了畔柔,現(xiàn)在我們獲到了相機(jī)圖片氯夷。
然后我還是選擇發(fā)送一個(gè)通知把照片傳給顯示頁(yè)。
結(jié)語(yǔ)
好了靶擦,好了腮考,不行了雇毫,不寫了。應(yīng)該也差不多了踩蔚。還有一些小的功能沒(méi)有寫棚放,一切都在代碼里面。