1. 程式人生 > >iOS uitableview自定義相簿(實現拍照並儲存在指定目錄以相簿的形式展示圖片)

iOS uitableview自定義相簿(實現拍照並儲存在指定目錄以相簿的形式展示圖片)

原理:
圖片的展示是通過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.當單個資料夾中,圖片過多時,載入較慢