iOS中從相冊(cè)選取多個(gè)照片或拍照,可滑動(dòng)

這兩天項(xiàng)目中需要用戶上傳多張圖片昭抒,或者實(shí)時(shí)拍照评也,并多個(gè)照片排列在一排。倒是花費(fèi)了我一番時(shí)間∶鸱担現(xiàn)在寫在這里盗迟。
先上波圖


展示圖.gif

拍照:


Paste_Image.png

在這里要用到github上的一個(gè)開(kāi)源第三方zlphotobrowser,不過(guò)這個(gè)第三方有很多bug熙含,自己拿來(lái)用不是很好使罚缕,需要花時(shí)間改。

由于最近工作比較忙怎静,就不一步步解釋了邮弹,直接將我自己寫的代碼貼一下
在ViewController.m中

#import "ViewController.h"
#import "UIImage+ZLPhotoLib.h"
#import "ZLPhoto.h"
#import "OneTableViewCell.h"
//#import "UIButton+WebCache.h"
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource,ZLPhotoPickerBrowserViewControllerDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
{
    int MaxPhotos; //照片數(shù)量
    //在取消相冊(cè)之前,記錄下當(dāng)前標(biāo)記過(guò)的照片數(shù)量
    NSMutableArray *_biaojiArr;
}
@property (nonatomic , strong) UITableView *tableView;
@property (nonatomic , strong) NSMutableArray *assets;
@property (nonatomic, strong) NSMutableArray *arr;//拍照數(shù)組
@property (nonatomic, strong) ZLCameraViewController *cameraVc;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    MaxPhotos = 5;
    _biaojiArr = [[NSMutableArray alloc] init];
    [self subTableView];
    
}

- (void)subTableView {
    _tableView = [[UITableView alloc   ] initWithFrame:self.view.frame];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];
}

- (NSMutableArray *)assets{
    if (!_assets) {
        _assets = [NSMutableArray array];
    }
    return _assets;
}

- (NSMutableArray *)arr {
    if (!_arr) {
        _arr = [NSMutableArray array];
    }
    return _arr;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellID = @"jiege";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
    
    if (indexPath.row == 2) {
        OneTableViewCell *cell = [[OneTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"one"];
        cell.selectBtn.backgroundColor = [UIColor blueColor];
        [cell.selectBtn addTarget:self action:@selector(diaoyao) forControlEvents:UIControlEventTouchUpInside];
        
        cell.collectionView.showsHorizontalScrollIndicator = NO;
        cell.collectionView.delegate = self;
        cell.collectionView.dataSource = self;
        
        return cell;
    }
    return cell;
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.assets.count;
}

- ( CGSize )collectionView:( UICollectionView *)collectionView layout:( UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:( NSIndexPath *)indexPath{
    return CGSizeMake ( 60 , 30 );
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 15;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath];
    
    UIImageView *photoView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
    photoView.backgroundColor = [UIColor yellowColor];
    [cell.contentView addSubview:photoView];
    photoView.tag = indexPath.row+1000;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapp:)];
    photoView.userInteractionEnabled = YES;
    [photoView addGestureRecognizer:tap];
    
    //創(chuàng)建刪除按鈕
    UIImageView *deleteView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
    deleteView.backgroundColor = [UIColor redColor ];
    [photoView addSubview:deleteView];
    deleteView.tag = indexPath.row + 1100;
    UITapGestureRecognizer *detap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapp:)];
    deleteView.userInteractionEnabled = YES;
    [deleteView addGestureRecognizer:detap];
    
    
    NSLog(@"5555555=assets =  %ld", self.assets.count);
    ZLPhotoAssets *asset = self.assets[indexPath.row];
//    ZLPhotoAssets *asset = _biaojiArr[indexPath.row];
    if ([asset isKindOfClass:[ZLPhotoAssets class]]) {
        photoView.image = asset.originImage;
    }else if ([asset isKindOfClass:[UIImage class]]) {
        photoView.image = (UIImage *)asset;
    }else if ([asset isKindOfClass:[ZLCamera class]]) {
        photoView.image = [(ZLCamera *)asset photoImage];
    }
    
    deleteView.backgroundColor = [UIColor redColor];
    
    return cell;
    
}

- (void)tapp:(UIGestureRecognizer *)tap {
    int index = (int)[tap view].tag;
    if (index == 1000) {
        //第一個(gè)
        NSLog(@"第一個(gè)");
        UIImageView *photoView = (UIImageView *)[self.view viewWithTag:index];
        ZLPhotoPickerBrowserViewController *browserVc = [[ZLPhotoPickerBrowserViewController alloc] init];
        [browserVc showHeadPortrait:photoView];
        
    }
    else if (index == 1001) {
        NSLog(@"第二個(gè)");
    }
    
    
    if (index == 1100) {
        //第一個(gè)差號(hào)
        NSLog(@"第一個(gè)差號(hào)");
        [self.assets removeObjectAtIndex:index % 1100];
        [_tableView reloadData];
    }
    
}

- (void)handleBtn {
//    ZLPhotoPickerViewController *pickerVc = [[ZLPhotoPickerViewController alloc] init];
//    // MaxCount, Default = 9
//    pickerVc.maxCount = 9;
//    // Jump AssetsVc
//    pickerVc.status = PickerViewShowStatusCameraRoll;
//    // Filter: PickerPhotoStatusAllVideoAndPhotos, PickerPhotoStatusVideos, PickerPhotoStatusPhotos.
//    pickerVc.photoStatus = PickerPhotoStatusPhotos;
//    // Recoder Select Assets
//    pickerVc.selectPickers = self.assets;
//    // Desc Show Photos, And Suppor Camera
//    pickerVc.topShowPhotoPicker = YES;
//    pickerVc.isShowCamera = YES;
//    // CallBack
//    pickerVc.callBack = ^(NSArray<ZLPhotoAssets *> *status){
//        self.assets = status.mutableCopy;
//        //        [self reloadScrollView];
//        NSLog(@"提取相冊(cè)完成,assets == %ld", self.assets.count);
//        [_tableView reloadData];
//    };
//    [pickerVc showPickerVc:self];
    NSLog(@"66666=assets =  %ld", self.assets.count);
//    _biaojiArr = [NSMutableArray arrayWithArray:self.assets];
    _biaojiArr = [self.assets mutableCopy];
    NSLog(@"_biaoji == %ld", _biaojiArr.count);
    ZLPhotoPickerViewController *pickerVc = [[ZLPhotoPickerViewController alloc] init];
    NSArray *array = [[NSArray alloc] initWithArray:self.assets];
    pickerVc.selectPickers = array;
    pickerVc.maxCount = MaxPhotos;
    
    for (ZLPhotoAssets *photo in array) {
        if ([photo isKindOfClass:[ZLCamera class]]){
            pickerVc.maxCount -= 1;
//            NSLog(@"333333=assets =  %ld", self.assets.count);

        } else if ([photo isKindOfClass:[ZLPhotoAssets class]]) {
            [self.assets removeObject:photo];
//            NSLog(@"22222=assets =  %ld", self.assets.count);
        }
//        NSLog(@"1111111=assets =  %ld", self.assets.count);

    }
    if (self.assets.count != 0) {
        pickerVc.maxCount = MaxPhotos - self.assets.count;
    }
    
    pickerVc.status = PickerViewShowStatusCameraRoll;
//    NSLog(@"444444=assets =  %ld", self.assets.count);
    [pickerVc showPickerVc:self];
    
    __weak typeof(self) weakSelf = self;
    pickerVc.callBack = ^(NSArray *assets){
        //        [weakSelf.assert removeAllObjects];
        [weakSelf.assets addObjectsFromArray:assets];
        [weakSelf.tableView reloadData];
    };
    //接受取消觀察者信息
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notice:) name:@"tongzhi" object:nil];

}

-(void)notice:(id)sender{
    NSLog(@"%@",sender);
    _assets = [_biaojiArr mutableCopy];
    NSLog(@"_assssss == %ld", _assets.count);
}

- (void)paizhao {
    //    //判斷攝像頭是否可用
    //    BOOL isCamera = [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];
    //
    //    if (!isCamera) {
    //        NSLog(@"沒(méi)有攝像頭");
    //        return;
    //    }
    //    //初始化圖片選擇控制器
    //    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    //    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;//設(shè)置通過(guò)照相來(lái)選取照片
    //
    //    imagePicker.allowsEditing = YES; //設(shè)置拍照時(shí)的下方的工具欄是否顯示消约,如果需要自定義拍攝界面肠鲫,則可把該工具欄隱藏
    //    imagePicker.delegate = self;
    //    [self presentViewController:imagePicker animated:YES completion:nil];
    NSLog(@"camera count == %ld", _cameraVc.maxCount);
    NSLog(@"asset == %ld", _assets.count);
    if (_assets.count >= MaxPhotos) {
        NSLog(@"當(dāng)前照片已經(jīng)到達(dá)上線");
    }
    _cameraVc = [[ZLCameraViewController alloc] init];
    // 拍照最多個(gè)數(shù)
    _cameraVc.maxCount = MaxPhotos-self.assets.count;
    __weak typeof(self) weakSelf = self;
    _cameraVc.callback = ^(NSArray *cameras){
        for (id object in cameras) {
            [weakSelf.assets addObject:object];
        }
//        [weakSelf.assets addObjectsFromArray:cameras];
        [weakSelf.tableView reloadData];
    };
    [_cameraVc showPickerVc:self];
    
}
- (void)diaoyao {
    //調(diào)用相冊(cè)或者拍照
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"請(qǐng)選擇獲取圖片操作" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *photos = [UIAlertAction actionWithTitle:@"從相冊(cè)中" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self handleBtn];
        
    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        
    }];
    
    UIAlertAction *makePhotos = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self paizhao];
        
    }];
    [alert addAction:photos];
    [alert addAction:makePhotos];
    [alert addAction:cancel];
    
    [self presentViewController:alert animated:YES completion:^{
        
    }];
    
}

里面用到的collectionView员帮,是我們自定義cell里面的

static NSString *const cellId = @"cellId";
static NSString *const headerId = @"headerId";
static NSString *const footerId = @"footerId";
- (UICollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
        _collectionView = [[ UICollectionView alloc ] initWithFrame:CGRectMake(80, 10, self.frame.size.width - 80 , 30) collectionViewLayout :layout];
        _collectionView.backgroundColor = [UIColor whiteColor];
        [_collectionView registerClass :[UICollectionViewCell class ] forCellWithReuseIdentifier : cellId ];
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerId];
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerId];
        
        [self.contentView addSubview:_collectionView];

    }
    return _collectionView;
}

運(yùn)行后如下:


測(cè)試.gif

如果你喜歡的話或粮,別忘了點(diǎn)贊,如果幫到了你的話捞高,別忘了請(qǐng)我吃辣條如果你有不懂氯材,可以留言,我有時(shí)間會(huì)回復(fù)的為了更美好的明天硝岗,睡覺(jué)氢哮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市型檀,隨后出現(xiàn)的幾起案子冗尤,更是在濱河造成了極大的恐慌,老刑警劉巖胀溺,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件裂七,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仓坞,警方通過(guò)查閱死者的電腦和手機(jī)背零,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)无埃,“玉大人徙瓶,你說(shuō)我怎么就攤上這事毛雇。” “怎么了侦镇?”我有些...
    開(kāi)封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵灵疮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我虽缕,道長(zhǎng)始藕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任氮趋,我火速辦了婚禮伍派,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剩胁。我一直安慰自己诉植,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布昵观。 她就那樣靜靜地躺著晾腔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啊犬。 梳的紋絲不亂的頭發(fā)上灼擂,一...
    開(kāi)封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音觉至,去河邊找鬼剔应。 笑死,一個(gè)胖子當(dāng)著我的面吹牛语御,可吹牛的內(nèi)容都是我干的峻贮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼应闯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纤控!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起碉纺,我...
    開(kāi)封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤船万,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后骨田,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體耿导,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年盛撑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碎节。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抵卫,死狀恐怖狮荔,靈堂內(nèi)的尸體忽然破棺而出胎撇,到底是詐尸還是另有隱情,我是刑警寧澤殖氏,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布晚树,位于F島的核電站,受9級(jí)特大地震影響雅采,放射性物質(zhì)發(fā)生泄漏爵憎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一婚瓜、第九天 我趴在偏房一處隱蔽的房頂上張望宝鼓。 院中可真熱鬧,春花似錦巴刻、人聲如沸愚铡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沥寥。三九已至,卻和暖如春柠座,著一層夾襖步出監(jiān)牢的瞬間邑雅,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工妈经, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淮野,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓狂塘,卻偏偏與公主長(zhǎng)得像录煤,于是被迫代替她去往敵國(guó)和親鳄厌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荞胡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件了嚎、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評(píng)論 4 62
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議泪漂。它實(shí)...
    香橙柚子閱讀 23,864評(píng)論 8 183
  • Github地址:-CollectionViewLayout-CollectionViewFlowLayout- ...
    大沖哥閱讀 5,210評(píng)論 1 10
  • 生命來(lái)來(lái)往往萝勤,它沒(méi)有來(lái)日方長(zhǎng)。 16年底呐伞,我終于考過(guò)了專業(yè)資格證書敌卓,第五次報(bào)名,第四次進(jìn)考場(chǎng)伶氢,第三個(gè)城市趟径,第二個(gè)省...
    Mi折子戲閱讀 318評(píng)論 0 0
  • 今天一直反反復(fù)復(fù)聽(tīng)零極限中文版CD持續(xù)清理內(nèi)在瘪吏,冥想,皈命蜗巧,學(xué)習(xí)面經(jīng)掌眠,聽(tīng)好好說(shuō)話,繼續(xù)108拜幕屹,又聽(tīng)了喜馬拉...
    Namaste_洛桑real閱讀 179評(píng)論 0 0