最近項目告一段落盛正,也有時間來總結(jié)一下使用第三方控件遇到的小坑了雀扶。
之前遇到的“來自未來的照片”應(yīng)該算是圓滿解決关摇,之后又出現(xiàn)了新的需求荒叶,故又遇到了一些新的問題。
如題输虱。
那么這個問題是怎么產(chǎn)生的呢些楣?TZImage如果是單選模式下,而我們又沒有開啟選中按鈕的時候。點(diǎn)擊圖片會進(jìn)入到圖片預(yù)覽中戈毒,此時如果我們選好的圖片點(diǎn)擊右上方的完成按鈕艰猬,TZimage選擇器會自動dismiss掉(如果我們沒有設(shè)置autoDismiss的話)
/// Default is YES, if set NO, the picker don't dismiss itself.
/// 默認(rèn)為YES,如果設(shè)置為NO, 選擇器將不會自己dismiss
@property(nonatomic, assign) BOOL autoDismiss;
OK埋市,那么重點(diǎn)來了冠桃。我們現(xiàn)在的需求就是不讓其自行dismiss,我們可能會突然不滿意現(xiàn)在選中的圖片了道宅,想要返回到photoPicker中再重新選擇圖片食听。那么如果我們之前dismiss了,就需要重新打開相冊污茵,造成一些不太好的用戶體驗樱报。所以我們想要用戶可以重復(fù)預(yù)覽,并且重新選擇照片(我們的需求是選擇好照片后進(jìn)入編輯照片頁面泞当,當(dāng)然照片編輯器不是TZImage提供的)迹蛤。此時問題出現(xiàn)了,我們每次點(diǎn)擊照片時預(yù)覽都是OK的襟士,沒有毛病盗飒。但是當(dāng)選中一張照片進(jìn)入編輯頁面后,再次返回到預(yù)覽頁換一張圖片進(jìn)入編輯頁陋桂,拿到的永遠(yuǎn)是第一次選中的圖片逆趣。
起初我以為是每次返回的都是同一個對象,于是打上斷點(diǎn)查看一下嗜历。
<TZAssetModel: 0x1c045c830> //第一次返回
<TZAssetModel: 0x1c0641b30> //第二次返回
可以看到每次返回的對象是不同的宣渗。那么奇怪了,不同的Asset對象梨州,顯示的卻是同一張圖片痕囱?
繼續(xù)查看TZImage的源碼,發(fā)現(xiàn)了這么一個東西:
/// The photos user have selected
/// 用戶選中過的圖片數(shù)組
@property (nonatomic, strong) NSMutableArray *selectedAssets;
@property (nonatomic, strong) NSMutableArray<TZAssetModel *> *selectedModels;
看來我們只看當(dāng)前選中的圖片還是太天真了摊唇,TZImage選擇圖片全部都會存入這個選中的圖片數(shù)組中咐蝇。單選也不例外,從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中返回的圖片是一個數(shù)組巷查。問題找到了有序,一定是這個保存選中圖片的數(shù)組沒有更新。查看了一下代碼岛请,果然如此旭寿。
- (void)select:(UIButton *)selectButton {
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
TZAssetModel *model = _models[_currentIndex];
if (!selectButton.isSelected) {
// 1. select:check if over the maxImagesCount / 選擇照片,檢查是否超過了最大個數(shù)的限制
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 / 如果沒有超過最大個數(shù)限制
} 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];
}
作者的思路還是很嚴(yán)禁的,如果是復(fù)選的情況崇败,或者是單選模式下有選中按鈕的情況盅称,是可以移除掉之前選中的圖片的肩祥。但是如果沒有選中按鈕,重新選擇照片時就無法移除之前選擇的照片(或許作者根本沒想過誰會這么奇葩缩膝,點(diǎn)了完成不dismiss卻要做點(diǎn)花里胡哨的)混狠。
那么好,問題找到了疾层,不是什么大問題将饺。上解決代碼:
// 如果沒有選中過照片 點(diǎn)擊確定時選中當(dāng)前預(yù)覽的照片
if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
TZAssetModel *model = _models[_currentIndex];
[_tzImagePickerVc.selectedModels addObject:model];
}
這是原來的代碼,我加了一個判斷:
TZAssetModel *model = _models[_currentIndex];
// 如果沒有選中過照片 點(diǎn)擊確定時選中當(dāng)前預(yù)覽的照片
if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
[_tzImagePickerVc.selectedModels addObject:model];
}
// 如果是單選痛黎,重新選擇了照片之后應(yīng)該移除之前選中的照片
else if (_tzImagePickerVc.maxImagesCount == 1) {
[_tzImagePickerVc.selectedModels removeAllObjects];
[_tzImagePickerVc.selectedModels addObject:model];
}
OK予弧,圓滿解決。暫時沒有遇到別的問題湖饱。
PS:如果各位同學(xué)是使用的pod導(dǎo)入的代碼掖蛤,不建議在pod中直接修改TZImage的源碼,原因是萬一使用pod更新了源碼井厌,之前做的修改可能就不存在了蚓庭。我是直接將TZImage拖入到了項目中,隨便你怎么鼓搗仅仆。
大佬們的鞭策呢彪置。。蝇恶。