前言
經過幾天的斷斷續續的編寫終于把這一個小項目完成了,現在剛剛完成,代碼看著不整潔,請多包涵。前幾天要弄個相冊多選和照相選圖的功能,以前做過單選上傳頭像之類的。但是多選確實不像那么簡單,github找了好多的例子,都是在用幾個框架。不是說人家封的不好,封的很好,但是鹵煮比較笨,看了好久還是馬馬虎虎。然后上網查了下資料,還是決定自己寫一個。
正文
多選主要是需要一個frameworks:AssetsLibrary。這個類的主要功能就是多選(個人理解,不對請見諒)。
首先,我們從相冊開始:要查看所有的相冊,簡單的思路大家應該都有:獲取相冊組---獲取相冊,但是怎么進行呢,AssetsLibrary的用處來了。
- (void)countOfAlbumGroup:(void(^)(ALAssetsGroup *yfGroup))block{ //計算有幾個相冊
[self enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
if (block) {
block(group);
}
}
} failureBlock:^(NSError *error) {
NSLog(@"獲取相冊錯誤,%@",error); }];
}
這個是計算相冊數,可能手機相冊會有好幾個,所以要查看一下有幾個,畢竟用戶有很大的可能只會選擇某一個相冊里面的某一張相片。我是把這個方法拿了出來專門創建了一個類,這樣代碼思路會清晰一些。既然我們知道有幾個相冊了,每個相冊的一些信息也知道了,那么我們應該去顯示某一個相冊里面的所有照片了呀。這一步的代碼來了:
/** * 獲得一個相冊有多少照片 * */
- (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);
} }];}
這個方法的一個參數group,就是上一個代碼段得到的相冊group,拿到group之后就去求里面所有的照片。這里涉及到兩個點我說一下:### YFSelfImage這是一個我自己稍微封裝了uiimage的一個類
/** * 用于儲存相冊圖片,附有一個asset信息,用于圖片的其他處理 * */#import#import@interface YFSelfImage : UIImage
//可能需要的圖片信息
@property(nonatomic,strong)ALAsset *asset;
@end
比普通的UIImage多了一個屬性,asset。這一個就是要說的第二個點。
ALAsset
這一個類應該是多選里面最關聯的一個類了,它有照片的信息關聯,比如縮略圖之類的都可以通過它獲取。所以,我們多選全靠它去做事情。(關于用法和屬性,請google吧,網上有很多很多)。
好了,現在相冊里面的照片也獲取了,我要把它都顯示出來了,哎呀呀呀呀,龜派氣功波~~~~~~
- (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;
}
然后我們可以查看效果了:
相冊組:
相冊:
好了,基本的顯示完成了,大家也看到了,我上面有個完成按鈕。那么我們是不是需要在照片那來個選擇按鈕,然后我們得到選擇的圖片是吧,不然只是實現查看相冊有什么卵用。
再次編輯collectionview:
YFShowAlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:SHOWCELL forIndexPath:indexPath];
cell.selectBtn.tag = cellIndex;
//按鈕選中塊
__weak typeof(self)weakSelf = self;
cell.selectedBlock = ^(NSInteger index){
//把選中的圖片放倒一個數組里面
[weakSelf.selectedArray addObject:[weakSelf.dataArray objectAtIndex:index]];
selectBtn.userInteractionEnabled = YES;
};
//取消選定
cell.cancelBlock = ^(NSInteger index){
//找出取消的cell
YFSelfImage *oldImage = [weakSelf.dataArray objectAtIndex:index];
//從選中的數組去除
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;
}
再來看一下效果:
好了,現在我們是可以選擇了,現在我們要實現的是把我們選擇的照片拿到放到一個數組里面保存使用。前段代碼大家應該看見了,照片按鈕的選中與取選操作都謝了,我們現在完成“完成”這個按鈕操作了:
/**
* 完成選定
*/
- (void)successChoose{
//把選擇的圖片傳送過去
NSDictionary *dic = @{@"cellImage":self.selectedArray};
[[NSNotificationCenter defaultCenter]postNotificationName:@"pushImage" object:nil userInfo:dic];
//退出模態
[self dismissViewControllerAnimated:YES completion:^{
//這一步確保退出到顯示界面的時候顯示相冊組控制器一定退出
[self.navigationController popViewControllerAnimated:YES];
}];
}
這個有個解釋點:
就是數退出模態后又做了一次導航pop。因為這個項目的界面布局是:
所以,我從單相冊顯示界面dismiss相當于直接回到開始界面,但是你在下一次在進入相冊組界面的時候會出問題,它會直接進入單相冊顯示界面,也就是說在你dismiss之后后者兩個界面貌似沒有釋放的樣子,還是記住了相冊組界面push到單相冊界面的狀態。所以我在此處做了一個pop,防止出現這個問題。
在完成按鈕時,我已經選擇了通過通知把數組帶回了開始界面。所以開始界面會有我們所選擇的照片的顯示。
這里說一下,這個刪除事件我就不講了,大家一看應該都懂的。略過~~~~~~
好了,現在開始相機選擇照片這一塊:
首先我們打開一下相冊,固定死代碼:
/**
* 打開相機
*/
- (void)showCamera{
//選擇相機
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
UIImagePickerController *picker = [[UIImagePickerController alloc] init];//初始化
picker.delegate = self;
// picker.allowsEditing = YES;//設置可編輯
picker.sourceType = sourceType;
//進入照相界面
[[self getCurrentVC] presentViewController:picker animated:YES completion:nil];
}
然后嘞,嘎嘎,照了照片之后,我們選擇這張照片,那么學問來了,我們選擇這張照片可以直接去
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{}
這個代理里面去做操作,當然為了和相冊多選照片的屬性一致,我們需要做點操作。首先思路應該是把照的照片先放到相冊,然后我們去相冊去拿到這個相冊最后一張圖片,就是這個相機照的圖片。
多說無益,上代碼:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{
// //圖片
UIImage *image;
//判斷是不是從相機過來的
if (picker.sourceType != UIImagePickerControllerSourceTypePhotoLibrary) {
//關閉相機
[picker dismissViewControllerAnimated:YES completion:nil];
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
//通過判斷picker的sourceType,如果是拍照則保存到相冊去.非常重要的一步,不然,無法獲取照相的圖片
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
}
/**
* 確定相機圖片保存到系統相冊后,進行圖片獲取
*/
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSLog(@"已保存");
//操作獲得的照片,我這是直接顯示,你那個你加到你顯示的一組里面去顯示去就好了
ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];
//操作獲得的照片,我這是直接顯示,你那個你加到你顯示的一組里面去顯示去就好了
[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];
}];
}
好了,現在我們獲到了相機圖片。
然后我還是選擇發送一個通知把照片傳給顯示頁。
結語
好了,好了,不行了,不寫了。應該也差不多了。還有一些小的功能沒有寫,一切都在代碼里面。