关于TZImagePickerController单选图片返回重复的问题

最近项目告一段落,也有时间来总结一下使用第三方控件遇到的小坑了。
之前遇到的“来自未来的照片”应该算是圆满解决,之后又出现了新的需求,故又遇到了一些新的问题。
如题。
那么这个问题是怎么产生的呢?TZImage如果是单选模式下,而我们又没有开启选中按钮的时候。点击图片会进入到图片预览中,此时如果我们选好的图片点击右上方的完成按钮,TZimage选择器会自动dismiss掉(如果我们没有设置autoDismiss的话)

/// Default is YES, if set NO, the picker don't dismiss itself.
/// 默认为YES,如果设置为NO, 选择器将不会自己dismiss
@property(nonatomic, assign) BOOL autoDismiss;

OK,那么重点来了。我们现在的需求就是不让其自行dismiss,我们可能会突然不满意现在选中的图片了,想要返回到photoPicker中再重新选择图片。那么如果我们之前dismiss了,就需要重新打开相册,造成一些不太好的用户体验。
75B2F3D4D388A6A775C17AADC341DBD0.jpg

所以我们想要用户可以重复预览,并且重新选择照片(我们的需求是选择好照片后进入编辑照片页面,当然照片编辑器不是TZImage提供的)。此时问题出现了,我们每次点击照片时预览都是OK的,没有毛病。但是当选中一张照片进入编辑页面后,再次返回到预览页换一张图片进入编辑页,拿到的永远是第一次选中的图片。

起初我以为是每次返回的都是同一个对象,于是打上断点查看一下。
<TZAssetModel: 0x1c045c830> //第一次返回
<TZAssetModel: 0x1c0641b30> //第二次返回
可以看到每次返回的对象是不同的。那么奇怪了,不同的Asset对象,显示的却是同一张图片?
继续查看TZImage的源码,发现了这么一个东西:

/// The photos user have selected
/// 用户选中过的图片数组
@property (nonatomic, strong) NSMutableArray *selectedAssets;
@property (nonatomic, strong) NSMutableArray<TZAssetModel *> *selectedModels;

看来我们只看当前选中的图片还是太天真了,TZImage选择图片全部都会存入这个选中的图片数组中。单选也不例外,从TZImage的block中也能看出来

@property (nonatomic, copy) void (^didFinishPickingPhotosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);
@property (nonatomic, copy) void (^didFinishPickingPhotosWithInfosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos);

可以看到这个block中返回的图片是一个数组。问题找到了,一定是这个保存选中图片的数组没有更新。查看了一下代码,果然如此。

- (void)select:(UIButton *)selectButton {
    TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
    TZAssetModel *model = _models[_currentIndex];
    if (!selectButton.isSelected) {
        // 1. select:check if over the maxImagesCount / 选择照片,检查是否超过了最大个数的限制
        if (_tzImagePickerVc.selectedModels.count >= _tzImagePickerVc.maxImagesCount) {
            NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a maximum of %zd photos"], _tzImagePickerVc.maxImagesCount];
            [_tzImagePickerVc showAlertWithTitle:title];
            return;
            // 2. if not over the maxImagesCount / 如果没有超过最大个数限制
        } else {
            [_tzImagePickerVc.selectedModels addObject:model];
            if (self.photos) {
                [_tzImagePickerVc.selectedAssets addObject:_assetsTemp[_currentIndex]];
                [self.photos addObject:_photosTemp[_currentIndex]];
            }
            if (model.type == TZAssetModelMediaTypeVideo && !_tzImagePickerVc.allowPickingMultipleVideo) {
                [_tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Select the video when in multi state, we will handle the video as a photo"]];
            }
        }
    } else {
        NSArray *selectedModels = [NSArray arrayWithArray:_tzImagePickerVc.selectedModels];
        for (TZAssetModel *model_item in selectedModels) {
            if ([[[TZImageManager manager] getAssetIdentifier:model.asset] isEqualToString:[[TZImageManager manager] getAssetIdentifier:model_item.asset]]) {
                // 1.6.7版本更新:防止有多个一样的model,一次性被移除了
                NSArray *selectedModelsTmp = [NSArray arrayWithArray:_tzImagePickerVc.selectedModels];
                for (NSInteger i = 0; i < selectedModelsTmp.count; i++) {
                    TZAssetModel *model = selectedModelsTmp[i];
                    if ([model isEqual:model_item]) {
                        [_tzImagePickerVc.selectedModels removeObjectAtIndex:i];
                        break;
                    }
                }
                // [_tzImagePickerVc.selectedModels removeObject:model_item];
                if (self.photos) {
                    // 1.6.7版本更新:防止有多个一样的asset,一次性被移除了
                    NSArray *selectedAssetsTmp = [NSArray arrayWithArray:_tzImagePickerVc.selectedAssets];
                    for (NSInteger i = 0; i < selectedAssetsTmp.count; i++) {
                        id asset = selectedAssetsTmp[i];
                        if ([asset isEqual:_assetsTemp[_currentIndex]]) {
                            [_tzImagePickerVc.selectedAssets removeObjectAtIndex:i];
                            break;
                        }
                    }
                    // [_tzImagePickerVc.selectedAssets removeObject:_assetsTemp[_currentIndex]];
                    [self.photos removeObject:_photosTemp[_currentIndex]];
                }
                break;
            }
        }
    }
    model.isSelected = !selectButton.isSelected;
    [self refreshNaviBarAndBottomBarState];
    if (model.isSelected) {
        [UIView showOscillatoryAnimationWithLayer:selectButton.imageView.layer type:TZOscillatoryAnimationToBigger];
    }
    [UIView showOscillatoryAnimationWithLayer:_numberImageView.layer type:TZOscillatoryAnimationToSmaller];
}

作者的思路还是很严禁的,如果是复选的情况,或者是单选模式下有选中按钮的情况,是可以移除掉之前选中的图片的。但是如果没有选中按钮,重新选择照片时就无法移除之前选择的照片(或许作者根本没想过谁会这么奇葩,点了完成不dismiss却要做点花里胡哨的)。

那么好,问题找到了,不是什么大问题。上解决代码:

// 如果没有选中过照片 点击确定时选中当前预览的照片
    if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
        TZAssetModel *model = _models[_currentIndex];
        [_tzImagePickerVc.selectedModels addObject:model];
    }

这是原来的代码,我加了一个判断:

 TZAssetModel *model = _models[_currentIndex];
    // 如果没有选中过照片 点击确定时选中当前预览的照片
    if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
        [_tzImagePickerVc.selectedModels addObject:model];
    }
    //  如果是单选,重新选择了照片之后应该移除之前选中的照片
    else if (_tzImagePickerVc.maxImagesCount == 1) {
        [_tzImagePickerVc.selectedModels removeAllObjects];
        [_tzImagePickerVc.selectedModels addObject:model];
    }

OK,圆满解决。暂时没有遇到别的问题。

PS:如果各位同学是使用的pod导入的代码,不建议在pod中直接修改TZImage的源码,原因是万一使用pod更新了源码,之前做的修改可能就不存在了。我是直接将TZImage拖入到了项目中,随便你怎么鼓捣。

大佬们的鞭策呢。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 前言 之前一篇文章里,我详细的讲解了一些基本关键词以及基本概念,这里再简要列出来,再温故一下。 SEL 方法的名字...
    默默的前行阅读 321评论 0 1
  • DAY43 今天从夏河一路坐车到合作,吃了午饭就继续坐车来到了目的地――郎木寺,一个很神奇的镇子。一江分两寺,一镇...
    小馅儿饼看星星阅读 175评论 0 2
  • 今天最需要检讨的地方有看书看的不够,本来需要看一百页的,但没看够,只看了三十页,连最低的也没看够,另外,还有自己2...
    森林飞鹰阅读 93评论 0 0
  • 现在的我对童年的记忆非常的模糊: 几张照片、几个小伙伴、哥哥弟弟。扔沙包、跳皮筋、跳房子、砸瓶儿盖、摔方宝、拍洋画...
    Da金子阅读 328评论 3 3