iOS uitableview自定義相簿(實現拍照並儲存在指定目錄以相簿的形式展示圖片)
阿新 • • 發佈:2019-02-11
原理:
圖片的展示是通過uitableview實現。照片的展示以及選擇(uitableviewce’l’l)是通過倆個uibutton的疊加完成。通過設定每個uibutton的tag,並在viewcontroller中實現cell的delegate來實現對uibutton的監聽。
.h檔案
#import <UIKit/UIKit.h>
#import "PhotoObject.h"
#import "Comm.h"
#import "PhotoTableViewCell.h"
#import "MBProgressHUD.h"
@protocol PhotoViewControllerDelegate <NSObject>
-(void)passSelectPhoto :(NSMutableArray *) array;
@end
@interface PhotoViewController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITableViewDelegate,UITableViewDataSource,PhotoTableViewCellDelegate>
{
NSFileManager *fileMgr;
NSMutableArray *photoArray;
NSString * photoSavePath;
NSString * photoFileName;
MBProgressHUD *HUD;
NSMutableArray *passmutableArray;
NSString *datafiloderpath;
}
@property (strong, nonatomic) IBOutlet UITableView *photoTableView;
@property (strong, nonatomic) IBOutlet UIView *backBtn;
@property (strong, nonatomic) IBOutlet UIButton *tackPhotoBtn;
@property (strong, nonatomic) IBOutlet UIButton *cancelBtn;
@property (strong, nonatomic) IBOutlet UIButton *finishBtn;
@property (strong, nonatomic) id <PhotoViewControllerDelegate> delegate;
.m檔案
#import "PhotoViewController.h"
#import "AppDelegate.h"
@interface PhotoViewController ()
@end
@implementation PhotoViewController
@synthesize photoTableView;
@synthesize finishBtn;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[AppDelegate storyBoradAutoLay:self.view];
fileMgr = [NSFileManager defaultManager];
photoArray=[[NSMutableArray alloc]init];
passmutableArray=[[NSMutableArray alloc] init];
HUD = [[MBProgressHUD alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/2, 300, 100)];
[self.view addSubview:HUD];
//如果設定此屬性則當前的view置於後臺
// HUD.dimBackground = YES;
//設定對話方塊文字
HUD.labelText = @"獲取照片資料中";
//顯示對話方塊
[HUD showAnimated:YES whileExecutingBlock:^{
//對話方塊顯示時需要執行的操作
//指向檔案目錄
NSDate * date=[NSDate date];
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
NSString *datefloder= [dateformatter stringFromDate:date];
datafiloderpath=[NSString stringWithFormat:@"%@/",datefloder];
NSString *documentsDirectory= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
photoSavePath=[NSString stringWithFormat:@"%@/%@%@", documentsDirectory,photoPath,datafiloderpath];
if (![fileMgr fileExistsAtPath:photoSavePath])
{
[fileMgr createDirectoryAtPath:photoSavePath withIntermediateDirectories:YES attributes:nil error:nil];
}
photoArray=[self getFilenamelistOfType:@"png" fromDirPath:photoSavePath];
photoTableView.delegate=self;
photoTableView.dataSource=self;
sleep(5);
} completionBlock:^{
//操作執行完後取消對話方塊
//[photoTableView reloadData];
[HUD removeFromSuperview];
}];
}
-(void)viewDidUnload
{
}
-(void)viewDidLayoutSubviews
{
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)btnControll:(UIButton *)sender {
switch (sender.tag) {
//返回
case 0:
[self dismissModalViewControllerAnimated:YES];
[self.delegate passSelectPhoto:passmutableArray];
break;
// 拍照
case 1:
[ self takePic ];
break;
// 取消
case 2:
[self dismissModalViewControllerAnimated:YES];
[self.delegate passSelectPhoto:passmutableArray];
break;
//確定
case 3:
[self dismissModalViewControllerAnimated:YES];
[self.delegate passSelectPhoto:passmutableArray];
break;
default:
break;
}
}
-(NSMutableArray *)getFilenamelistOfType:(NSString *)type fromDirPath:(NSString *)dirPath
{
NSMutableArray *filenamelist = [[NSMutableArray alloc]init];
NSArray *tmplist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dirPath error:nil];
for (NSString *filename in tmplist) {
NSString *fullpath = [dirPath stringByAppendingPathComponent:filename];
if ([self isFileExistAtPath:fullpath]) {
if ([[filename pathExtension] isEqualToString:type]) {
PhotoObject *ob=[[PhotoObject alloc]init];
ob.PhotoName=filename;
ob.PhotoPath=fullpath;
ob.PhotoIsChecked=NO;
[filenamelist addObject:ob];
}
}
}
return filenamelist;
}
-(BOOL)isFileExistAtPath:(NSString*)fileFullPath {
BOOL isExist = NO;
isExist = [[NSFileManager defaultManager] fileExistsAtPath:fileFullPath];
return isExist;
}
-(void)takePic
{
//先設定sourceType為相機,然後判斷相機是否可用(ipod)沒相機,不可用將sourceType設定為相片庫
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
//sourceType = UIImagePickerControllerSourceTypeCamera; //照相機
//sourceType = UIImagePickerControllerSourceTypePhotoLibrary; //圖片庫
//sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; //儲存的相片
UIImagePickerController *picker = [[UIImagePickerController alloc] init];//初始化
picker.delegate = self;
picker.allowsEditing = NO;//設定可編輯
picker.sourceType = sourceType;
if([[[UIDevice
currentDevice] systemVersion] floatValue]>=8.0) {
self.modalPresentationStyle=UIModalPresentationOverCurrentContext;
}
[self presentModalViewController:picker animated:YES];//進入照相介面
}
-(UIImage *) addOverlayToBaseImage :(UIImage *) img
{
return img;
}
-(UIImage *)changImageRotation:(UIImage *)image rotation:(UIImageOrientation)orientation
{
long double rotate = 0.0;
CGRect rect;
float translateX = 0;
float translateY = 0;
float scaleX = 1.0;
float scaleY = 1.0;
switch (orientation) {
case UIImageOrientationLeft:
rotate = M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = 0;
translateY = -rect.size.width;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationRight:
rotate = 3 * M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = -rect.size.height;
translateY = 0;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationDown:
rotate = M_PI;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = -rect.size.width;
translateY = -rect.size.height;
break;
default:
rotate = 0.0;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = 0;
translateY = 0;
break;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
//做CTM變換
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextRotateCTM(context, rotate);
CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//繪製圖片
CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
return newPic;
}
- (UIImage *)compressImage:(UIImage *)image toMaxFileSize:(NSInteger)maxFileSize {
CGFloat compression = 0.9f;
CGFloat maxCompression = 0.1f;
NSData *imageData = UIImageJPEGRepresentation(image, compression);
while ([imageData length] > maxFileSize && compression > maxCompression) {
compression -= 0.1;
imageData = UIImageJPEGRepresentation(image, compression);
}
UIImage *compressedImage = [UIImage imageWithData:imageData];
return compressedImage;
}
#pragma UIImagePickerControllerDelegate
// 選擇了圖片或者拍照
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
UIImage *baseImage = [info objectForKey:UIImagePickerControllerOriginalImage];
// baseImage= [self changImageRotation:baseImage rotation:90 ];
baseImage=[self imageByScalingToSize:CGSizeMake(320, 480) :baseImage];
baseImage=[self compressImage:baseImage toMaxFileSize:100];
if (baseImage == nil)
return;
UIImage * compositeImage = [self addOverlayToBaseImage:baseImage];
//NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc] init] ;
[formatter setDateFormat:@"yyyyMMddHHMMSS"];
NSString* str = [formatter stringFromDate:date];
photoFileName=[NSString stringWithFormat:@"%@%@",str,@".png"];
//給照片按拍攝時間命名
NSString *uniquePath=[photoSavePath stringByAppendingPathComponent:photoFileName];
NSLog(@"-----%@",uniquePath);
BOOL result=[UIImageJPEGRepresentation(compositeImage, 0.5) writeToFile: uniquePath atomically:YES];
if (result)
{
PhotoObject *ob=[[PhotoObject alloc]init];
ob.PhotoName=photoFileName;
ob.PhotoPath=uniquePath;
ob.PhotoIsChecked=NO;
[photoArray addObject:ob];
[photoTableView reloadData];
NSLog(@"success");
}
[self dismissModalViewControllerAnimated:YES];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (UIImage *)imageByScalingToSize:(CGSize)targetSize :(UIImage *)image
{
UIImage *sourceImage = image;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (!CGSizeEqualToSize(imageSize, targetSize)) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(@"could not scale image");
return newImage ;
}
#pragma tableViewDelegate
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (photoArray.count%3==0) {
return photoArray.count/3;
}
else
{
return photoArray.count/3+1;
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//指定cellIdentifier為自定義的cell
static NSString *CellIdentifier = @"PhotoTableViewCell";
//自定義cell類
PhotoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//通過xib的名稱載入自定義的cell
cell = [[[NSBundle mainBundle] loadNibNamed:@"PhotoTableViewCell" owner:self options:nil] lastObject];
cell.delegate=self;
}
PhotoObject *object=[[PhotoObject alloc] init];
UIImage *sourceimage=[[UIImage alloc]init];
UIImage *imagethu=[[UIImage alloc]init];
NSInteger cellcount=3;
NSLog(@"%d",indexPath.row);
int lastRow=photoArray.count/3;
int lastCount=photoArray.count%3;
if (lastCount!=0) {
}
else
{
lastRow= lastRow+1;
}
if(lastRow==indexPath.row){
cell.imageBtn1.hidden=YES;
cell.imageBtn2.hidden=YES;
cell.imageBtn3.hidden=YES;
cell.imageBgBtn1.hidden=YES;
[cell.imageBgBtn1 setUserInteractionEnabled:NO];
cell.imageBgBtn2.hidden=YES;
[cell.imageBgBtn2 setUserInteractionEnabled:NO];
cell.imageBgBtn3.hidden=YES;
[cell.imageBgBtn3 setUserInteractionEnabled:NO];
if(lastCount==1){
cell.imageBtn1.hidden=NO;
cell.imageBgBtn1.hidden=NO;
cell.imageBtn1.tag=3*indexPath.row;
object=[photoArray objectAtIndex:(3*indexPath.row)];
if (object.PhotoIsChecked) {
[ cell.imageBtn1 setImage:[UIImage imageNamed:@"abc_btn_check_to_on_mtrl_015.png"] forState:UIControlStateNormal];
}
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
// imagethu=[self imageByScalingToSize:CGSizeMake(98, 98) :sourceimage];
[cell.imageBgBtn1 setBackgroundImage:sourceimage forState:UIControlStateNormal];
}
if(lastCount==2){
cell.imageBtn1.hidden=NO;
cell.imageBgBtn1.hidden=NO;
cell.imageBtn1.tag=3*indexPath.row;
object=[photoArray objectAtIndex:(3*indexPath.row)];
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
// imagethu=[self imageByScalingToSize:CGSizeMake(98, 98) :sourceimage];
[cell.imageBgBtn1 setBackgroundImage:sourceimage forState:UIControlStateNormal];
cell.imageBtn2.hidden=NO;
cell.imageBgBtn2.hidden=NO;
cell.imageBtn2.tag=3*indexPath.row+1;
NSLog(@"%d",3*indexPath.row+1);
object=[photoArray objectAtIndex:(3*indexPath.row+1)];
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
// imagethu=[self imageByScalingToSize:CGSizeMake(98, 98) :sourceimage];
[cell.imageBgBtn2 setBackgroundImage:sourceimage forState:UIControlStateNormal];
}
}else{
cell.imageBtn1.tag=3*indexPath.row;
object=[photoArray objectAtIndex:(3*indexPath.row)];
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
// imagethu=[self imageByScalingToSize:CGSizeMake(90, 73) :sourceimage];
[cell.imageBgBtn1 setBackgroundImage:sourceimage forState:UIControlStateNormal];
cell.imageBtn2.tag=3*indexPath.row+1;
object=[photoArray objectAtIndex:(3*indexPath.row+1)];
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
//imagethu=[self imageByScalingToSize:CGSizeMake(90, 73) :sourceimage];
[cell.imageBgBtn2 setBackgroundImage:sourceimage forState:UIControlStateNormal];
cell.imageBtn3.tag=3*indexPath.row+2;
object=[photoArray objectAtIndex:(3*indexPath.row+2)];
sourceimage=[UIImage imageWithContentsOfFile:object.PhotoPath];
//imagethu=[self imageByScalingToSize:CGSizeMake(90, 73) :sourceimage];
[cell.imageBgBtn3 setBackgroundImage:sourceimage forState:UIControlStateNormal];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%d",indexPath.row);
[tableView deselectRowAtIndexPath:indexPath animated:YES];//選中後的反顯顏色即刻消失
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 110;
}
int selectcount=0;
#pragma Phototableviewcelldelegate
- (void)SelectImageClicked:(UIButton *)button
{
NSInteger s=button.tag;
PhotoObject *sm=[photoArray objectAtIndex:s];
if (sm.PhotoIsChecked) {
sm.PhotoIsChecked=NO;
if (selectcount==0) {
return;
}
else
{
selectcount=selectcount-1;
[passmutableArray removeObject:sm];
[ button setImage:[UIImage imageNamed:@"abc_btn_check_to_on_mtrl_000.png"] forState:UIControlStateNormal];
NSString *btntile=[NSString stringWithFormat:@"完成(%d/5)",selectcount];
//finishBtn.titleLabel.text=btntile;
[finishBtn setTitle:btntile forState:(UIControlStateNormal)];
}
}else
{
if (selectcount>5) {
return;
}
else
{
selectcount=selectcount+1;
sm.PhotoIsChecked=YES;
[ button setImage:[UIImage imageNamed:@"abc_btn_check_to_on_mtrl_015.png"] forState:UIControlStateNormal];
[passmutableArray addObject:sm];
NSString *btntile=[NSString stringWithFormat:@"完成(%d/5)",selectcount];
//finishBtn.titleLabel.text=btntile;
[finishBtn setTitle:btntile forState:(UIControlStateNormal)];
}
}
NSLog(@"%d",button.tag);
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
cell的代理
cell.h
@protocol PhotoTableViewCellDelegate <NSObject>
- (void)SelectImageClicked:(UIButton *)button;
;
@end
cell.m
- (IBAction)imageBtnClicked:(UIButton *)sender {
[self.delegate SelectImageClicked:sender];
}
未實現:
1.點選圖片,出現圖片展示
2.當單個資料夾中,圖片過多時,載入較慢