美文网首页iOS相关攻城狮界面处理
iOS-相册图片多选和删除(含拍照)

iOS-相册图片多选和删除(含拍照)

作者: Super_Yi | 来源:发表于2016-06-17 16:39 被阅读10801次

    项目开发告一段落,没之前那么忙了,简书接着更新吧。
    之前有写过从相册选取单张照片,有网友留言问多图选择怎么做,本次就先更新这个吧

    先上效果图

    照片多选1.gif

    本次用的第三方框架做这个,但是需要考虑的地方也比较多,怎么把拍照和相册选取结合、删除照片后添加新照片时候的相册状态等等,所有的改变都是在操作数组。还需考虑图片的压缩上传。

    本次用的第三方框架为:QBImagePickerController 大家可以去github搜

    按照惯例,上代码,本次代码较多

    第一个控制器 .h里没啥代码

    #import "RRZShowEditViewController.h"
    #import "RRZSendShowTextCell.h"
    #import "RRZSendShowImageCell.h"
    #import "QBImagePickerController.h"
    #import "ShowEditItem.h"
    
    static NSString *sendShowTextCellID = @"SendShowTextCellID";
    static NSString *sendShowImageCellID = @"SendShowImageCellID";
    
    @interface RRZShowEditViewController ()<UITableViewDataSource, UITableViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate,  UIScrollViewDelegate,UIActionSheetDelegate,QBImagePickerControllerDelegate>
    
    @property (strong, nonatomic) UITableView *myTableView;
    /** model*/
    @property (strong, nonatomic) ShowEditItem *showEditItem;
    /** textView的text*/
    @property (strong, nonatomic) NSString *valueStr;
    /** 文本输入*/
    @property (weak, nonatomic) NumberofwordsTextView *textView;
    
    @property (strong, nonatomic) QBImagePickerController *imagePickerController;
    
    @end
    
    @implementation RRZShowEditViewController
    
    -(ShowEditItem *)showEditItem{
        if (!_showEditItem) {
            _showEditItem = [[ShowEditItem alloc]init];
            _showEditItem.selectedImages = @[].mutableCopy;
            _showEditItem.selectedAssetURLs = @[].mutableCopy;
        }
        return _showEditItem;
    }
    
    -(QBImagePickerController *)imagePickerController{
        if (!_imagePickerController) {
            _imagePickerController = [[QBImagePickerController alloc] init];
            _imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos;
            _imagePickerController.delegate = self;
            _imagePickerController.allowsMultipleSelection = YES;
            _imagePickerController.maximumNumberOfSelection = 9;
        }
        [_imagePickerController.selectedAssetURLs removeAllObjects];
        [_imagePickerController.selectedAssetURLs addObjectsFromArray:self.showEditItem.selectedAssetURLs];
        
        return _imagePickerController;
    }
    
    -(void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
    }
    
    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.title = @"晒一晒";
        [self setupTabelView];
        [self setupNavItem];
    }
    
    -(void)setupNavItem{
        
        UIBarButtonItem *rightItem = [UIBarButtonItem itemWithTitle:@"发布" highTitle:nil target:self action:@selector(sendClick) norColor:NavItemColor highColor:RGB_COLOR(200, 200, 200)];
        self.navigationItem.rightBarButtonItem = rightItem;
    }
    
    // 压缩图片
    - (NSData *)resetSizeOfImageData:(UIImage *)source_image maxSize:(NSInteger)maxSize
    {
        //先调整分辨率
        CGSize newSize = CGSizeMake(source_image.size.width, source_image.size.height);
        
        CGFloat tempHeight = newSize.height / 1024;
        CGFloat tempWidth = newSize.width / 1024;
        
        if (tempWidth > 1.0 && tempWidth > tempHeight) {
            newSize = CGSizeMake(source_image.size.width / tempWidth, source_image.size.height / tempWidth);
        }
        else if (tempHeight > 1.0 && tempWidth < tempHeight){
            newSize = CGSizeMake(source_image.size.width / tempHeight, source_image.size.height / tempHeight);
        }
        
        UIGraphicsBeginImageContext(newSize);
        [source_image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        //调整大小
        NSData *imageData;
        if (UIImagePNGRepresentation(newImage)) {
            imageData = UIImagePNGRepresentation(newImage);
        }else{
            imageData = UIImageJPEGRepresentation(newImage, 0.5);
        }
        
        NSUInteger sizeOrigin = [imageData length];
        NSUInteger sizeOriginKB = sizeOrigin / 1024;
        if (sizeOriginKB > maxSize) {
            NSData *finallImageData = UIImageJPEGRepresentation(newImage,0.50);
            return finallImageData;
        }
        
        return imageData;
    }
    
    -(void)sendClick{
        
        [self.view endEditing:YES];
        
        [HUDController showProgressLabel:@""];
        
        NSString *textStr = self.textView.text;
        textStr = [textStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
        
        if (textStr.length > 0 || self.showEditItem.selectedImages.count > 0) {
            DLog(@"发表晒一晒");
            
            NSMutableArray *tempImages = [[NSMutableArray alloc]init];
            for (int i = 0; i < self.showEditItem.selectedImages.count; i++) {
                UIImage *tempImage = self.showEditItem.selectedImages[i];
                
                NSData *imgData = [self resetSizeOfImageData:tempImage maxSize:150];
                tempImage = [UIImage imageWithData:imgData];
    
                [tempImages addObject:tempImage];
            }
            
            
            [[RRZNetworkController sharedController]sendShowInfoByRemark:self.textView.text myfiles:tempImages success:^(NSDictionary *data) {
                
                NSString *code = data[@"code"];
                if ([code isEqualToString:@"success"]) {
                    [HUDController hideHUDWithText:@"发表成功"];
                    
                    if (_sendSuccessBlock) {
                        _sendSuccessBlock();
                    }
                    
                    [self.navigationController popViewControllerAnimated:YES];
                }else{
                    [HUDController hideHUD];
                    NSString *message = data[@"message"];
                    if (message.length > 30) {
                        message = @"上传失败";
                    }
                    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
                    [alertView show];
                }
                
            } failure:^(NSDictionary *error) {
                
                [HUDController hideHUDWithText:NetworkError];
            }];
        }else{
            [HUDController hideHUDWithText:@"文字或图片不能为空"];
        }
    
    }
    
    -(void)setupTabelView{
        //    添加myTableView
        _myTableView = ({
            UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
            tableView.backgroundColor = [UIColor clearColor];
            tableView.dataSource = self;
            tableView.delegate = self;
            tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
            [tableView registerClass:[RRZSendShowTextCell class] forCellReuseIdentifier:sendShowTextCellID];
            [tableView registerClass:[RRZSendShowImageCell class] forCellReuseIdentifier:sendShowImageCellID];
            [self.view addSubview:tableView];
            [tableView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.edges.equalTo(self.view);
            }];
            tableView;
        });
    }
    
    #pragma mark - UITableViewDelegate
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 2;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        if (indexPath.row == 0) {
            RRZSendShowTextCell *cell = [tableView dequeueReusableCellWithIdentifier:sendShowTextCellID];
            self.textView = cell.numberTextView;
    //        cell.textValueChangedBlock = ^(NSString *valueStr){
    //            weakSelf.valueStr = valueStr;
    //        };
            return cell;
        }else{
            RRZSendShowImageCell *cell = [tableView dequeueReusableCellWithIdentifier:sendShowImageCellID];
            cell.item = self.showEditItem;
            __weak typeof(self) weakSelf = self;
            cell.addPicturesBlock = ^(){
                [weakSelf showActionForPhoto];
            };
            cell.deleteImageBlock = ^(ShowEditItem *item){
                weakSelf.showEditItem = item;
                [weakSelf.myTableView reloadData];
            };
            return cell;
        }
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        if (indexPath.row == 0) {
            return 200;
        }else{
            return 300;
        }
    }
    
    #pragma mark UIActionSheet M
    - (void)showActionForPhoto{
        UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照",@"从相册选取", nil];
        [actionSheet showInView:self.view];
    }
    
    #pragma mark - UIActionSheetDelegate
    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
        if (buttonIndex == 0) {
            DLog(@"拍照");
            if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                UIAlertView *alert= [[UIAlertView alloc] initWithTitle:nil message:@"该设备不支持拍照" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:NULL];
                [alert show];
            }else{
                UIImagePickerController *picker = [[UIImagePickerController alloc] init];
                picker.delegate = self;
                picker.allowsEditing = NO;//设置可编辑
                picker.sourceType = UIImagePickerControllerSourceTypeCamera;
                [self presentViewController:picker animated:YES completion:nil];//进入照相界面
            }
        }else if (buttonIndex == 1){
            DLog(@"相册");
            if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
                UIAlertView *alert= [[UIAlertView alloc] initWithTitle:nil message:@"该设备不支持从相册选取文件" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:NULL];
                [alert show];
            }else{
    
                UINavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:self.imagePickerController];
                [self presentViewController:navigationController animated:YES completion:NULL];
            }
        }
    }
    
    #pragma mark UIImagePickerControllerDelegate
    // 拍照回调
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
        UIImage *pickerImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        [self.showEditItem.selectedImages addObject:pickerImage];
        ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
        [assetsLibrary writeImageToSavedPhotosAlbum:[pickerImage CGImage] orientation:(ALAssetOrientation)pickerImage.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) {
            [self.showEditItem.selectedAssetURLs addObject:assetURL];
    //        [self.showEditItem addASelectedAssetURL:assetURL];
            [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
        }];
        [picker dismissViewControllerAnimated:YES completion:^{}];
    }
    
    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
    
    #pragma mark QBImagePickerControllerDelegate
    //相册回调
    - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets{
        [self.showEditItem.selectedImages removeAllObjects];
        
        NSMutableArray *selectedAssetURLs = [NSMutableArray new];
        [imagePickerController.selectedAssetURLs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            [selectedAssetURLs addObject:obj];
        }];
        self.showEditItem.selectedAssetURLs = selectedAssetURLs;
        
        for (int i = 0; i < assets.count; i++) {
            ALAsset *asset = assets[i];
            UIImage *tempImg = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];
            [self.showEditItem.selectedImages addObject:tempImg];
        }
        @weakify(self);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            self.showEditItem.selectedAssetURLs = selectedAssetURLs;
            dispatch_async(dispatch_get_main_queue(), ^{
                @strongify(self);
                [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
            });
        });
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    - (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController{
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    #pragma mark - scrollView 
    // 滚动结束编辑 收起键盘
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
        if (scrollView == self.myTableView) {
            [self.view endEditing:YES];
        }
    }
    
    - (void)dealloc
    {
        _myTableView.delegate = nil;
        _myTableView.dataSource = nil;
    }
    
    @end
    

    第二个控制器 .h

    
    #import <UIKit/UIKit.h>
    #import "NumberofwordsTextView.h"
    
    @interface RRZSendShowTextCell : UITableViewCell
    
    @property (weak, nonatomic) NumberofwordsTextView *numberTextView;
    
    @end
    

    第二个控制器 .m

    
    #define kTweetContentCell_ContentFont [UIFont systemFontOfSize:16]
    
    #import "RRZSendShowTextCell.h"
    
    @interface RRZSendShowTextCell()
    
    @end
    
    @implementation RRZSendShowTextCell
    
    - (void)awakeFromNib {
        [super awakeFromNib];
        // Initialization code
        self.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            
            NumberofwordsTextView *numberTextView = [[NumberofwordsTextView alloc] init];
            numberTextView.frame = CGRectMake(7, 7, SCREEN_WIDTH-7*2, 180);
            numberTextView.wordsMaxNumer = 300;
            numberTextView.placeHolder = @"写点什么来晒一晒吧...";
            numberTextView.textFont = [UIFont systemFontOfSize:14];
            [self addSubview:numberTextView];
            self.numberTextView = numberTextView;
        }
        return self;
    }
    
    @end
    

    第三个 .h

    #import <UIKit/UIKit.h>
    #import "ShowEditItem.h"
    
    @interface RRZSendShowImageCell : UITableViewCell
    
    @property (copy, nonatomic) void (^addPicturesBlock)();
    @property (copy, nonatomic) void (^deleteImageBlock)(ShowEditItem *toDelete);
    @property (nonatomic,strong) ShowEditItem *item;
    
    @end
    

    .m

    #define kShowImageCCell_Width floorf((SCREEN_WIDTH - 15*2- 10*3)/4)
    
    #import "RRZSendShowImageCell.h"
    #import "RRZShowEditImageCell.h"
    #import "UICustomCollectionView.h"
    
    static NSString *cellID = @"RRZShowImageCCellID";
    @interface RRZSendShowImageCell()<UICollectionViewDelegate,UICollectionViewDataSource>
    
    @property (strong, nonatomic) UICustomCollectionView *mediaView;
    @property (strong, nonatomic) NSMutableDictionary *imageViewsDict;
    /** <#注释#>*/
    @property (strong, nonatomic) NSArray *imgs;
    /** <#注释#>*/
    @property (weak, nonatomic) UIButton *deleteBtn;
    
    @end
    
    @implementation RRZSendShowImageCell
    
    -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
        if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
            self.height = 300;
            [self setupCollectionView];
            self.selectionStyle = UITableViewCellSelectionStyleNone;
            
            UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 0, SCREEN_WIDTH - 20, 1)];
            label.backgroundColor = RGB_COLOR(240, 240, 240);
            [self.contentView addSubview:label];
        }
        return self;
    }
    
    -(void)setupCollectionView{
        
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
        layout.itemSize = CGSizeMake(kShowImageCCell_Width, kShowImageCCell_Width);
        self.mediaView = [[UICustomCollectionView alloc]initWithFrame:CGRectMake(15, 10, SCREEN_WIDTH - 2 * 15, 280) collectionViewLayout:layout];
        self.mediaView.scrollEnabled = NO;
        [self.mediaView setBackgroundColor:[UIColor clearColor]];
        [self.mediaView registerNib:[UINib nibWithNibName:NSStringFromClass([RRZShowEditImageCell class]) bundle:nil] forCellWithReuseIdentifier:cellID];
        self.mediaView.dataSource = self;
        self.mediaView.delegate = self;
        [self.contentView addSubview:self.mediaView];
    }
    
    -(void)setItem:(ShowEditItem *)item{
        _item = item;
        
        [self.mediaView reloadData];
    }
    
    #pragma mark - UICollectionViewDelegate
    -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
        NSInteger num = self.item.selectedImages.count;
        return num < 9? num+ 1: num;
    }
    
    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
        RRZShowEditImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
        if (indexPath.row < self.item.selectedImages.count) {
            cell.img = self.item.selectedImages[indexPath.row];
        }else{
            cell.img = nil;
        }
        cell.deleteBtn.tag = indexPath.row;
        [cell.deleteBtn addTarget:self action:@selector(deleteBtnClick:) forControlEvents:UIControlEventTouchUpInside];
        self.deleteBtn = cell.deleteBtn;
        return cell;
    }
    
    -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
        
        if (indexPath.row == self.item.selectedAssetURLs.count || indexPath.row == self.item.selectedImages.count) {
            if (_addPicturesBlock) {
                _addPicturesBlock();
            }
        }
    }
    
    -(void)deleteBtnClick:(UIButton *)btn{
        NSInteger index = btn.tag;
        [self.item.selectedImages removeObjectAtIndex:index];
        [self.item.selectedAssetURLs removeObjectAtIndex:index];
        if (_deleteImageBlock) {
            _deleteImageBlock(_item);
        }
    }
    
    @end
    

    RRZShowEditImageCell.h 就不写了,就是自定义一个UICollectionViewCell
    NumberofwordsTextView 在文中也用到了,就不贴代码了 直接去gitHub上搜吧

    以上就是从相机或相册选取多图上传的代码实现,其他的描述就不写了,有问题可以留言

    相关文章

      网友评论

      • 4bcc357b9c15:能发个demo么,529414220@qq.com
      • 6198f5bcd0f0:https://github.com/Mark-Ma-1988/PhotoSolution
        建议用这个库,类似微信的图片多选界面,并且同时支持Objective-C和Swift
      • 空白_girl:能发个demo么,1194765093@qq.com
        leevyin:楼主 求个demo 619325292@qq.com
      • 欧德尔丶胡:楼主 求demo 768922975@qq.com
      • a8afab0b8df1:楼主,求给个demo,谢谢!844661939@qq.com
      • 琅琊玥:楼主,给个demo,最近项目需要做到这个,谢谢楼主了 或者给个链接也可以 谢谢楼主了 331126156@qq.com
      • OnePi:如何提示的只能选9张
        安静守护你:可以自行设置选择图片的最大数
      • 羊肉泡馍啊:楼主demo啊
      • 小小夕舞:你能把demo给我么
      • Liebling_zn:楼主 NumberofwordsTextView 这个在GitHub怎么搜不到呢,能否提供一下呢,邮箱 1342134321@qq.com,谢谢
      • yzhi00:非常感谢!
      • 木匠屯_王保长:能看一下您的ShowEditItem类的内部实现吗?
        Super_Yi:只是定义了一个模型
      • 1b468a290949:楼主,有demo吗
        ,求啊
        Super_Yi:好久没看简书了,没有demo,实际项目中的代码
        1b468a290949:我的qq邮箱949077657@qq.com,谢谢
      • rockyMJ:楼主求demo啊 非常感谢!!! rocky91maji@163.com
      • insence:NumberofwordsTextView在github搜索不到
        insence:我配置了好久,实在是没办法了,希望能提供demo,非常感谢
      • 2e84d2d66047:楼主相册里几个美女不错😂
      • beb4a1a5a100:358287178@qq.com
      • beb4a1a5a100:求demo 十分感谢
      • 流年忆时光:楼主 求demo suntingwork@126.com
      • 流年易逝_李:楼主,求份demo,谢谢,1365343119@qq.com
      • 一夜暴富两夜也行:demo 写好了吗,方便发一份不 312591441@qq.com
      • RiversMa:RRZShowEditImageCell 和 UICustomCollectionView 这两个文件能否分享一下
      • 萧旭:楼主大人,在相册回调方法中,有两处写到了
        self.showEditItem.selectedAssetURLs = selectedAssetURLs;

        一处是在遍历imagePickerController.selectedAssetURLs完成后,
        另一处是,在方法将要结束时的异步线程队列中,,,,

        不知这是何用意??
      • 09f10d172df3:楼主,有Demo吗?非常喜欢你的这种效果
      • 4978bcc96ecc:不写注释不是好的习惯
      • 易样年华:请问博主 ShowEditItem 这个model 定义的都是些什么属性????
        易样年华:@Berton_Yi 感谢
        Super_Yi:@james_XY
        #import "BaseModel.h"

        @interface ShowEditItem : BaseModel

        /** <#注释#>*/
        @property (strong, nonatomic) NSMutableArray *selectedImages;//对 selectedAssetURLs 操作即可,最好不要直接赋值。。应用跳转带的图片会直接对 tweetImages赋值

        @property (readwrite, nonatomic, strong) NSMutableArray *selectedAssetURLs;


        - (void)addASelectedAssetURL:(NSURL *)assetURL;
        - (void)deleteASelectedAssetURL:(NSURL *)assetURL;


        @EnD
      • 回味岁月:能不能发个Demo 330685809@qq.com 多谢
        Super_Yi:@回味岁月 用到的代码基本都贴出来了,你可以先复制到你工程中试试。改天不太忙的时候整理个demo出来,最近比较忙。
        Super_Yi:@e18969c82eb9 这个基本把用到的代码都贴出来了,没有单独写demo,直接从项目中拿出来的,可以直接使用

      本文标题:iOS-相册图片多选和删除(含拍照)

      本文链接:https://www.haomeiwen.com/subject/vxckkttx.html