我正在制作一个自定义 ImagePicker,类似于通常的 UIImagePickerController,除了您可以点击以选择最多 3 张照片。当您点击选择第一张照片时,一个小的 UIView 托盘将从底部滑入,所选缩略图将出现在那里。当您点击以选择第二张和第三张照片时,它们将被添加到选定的照片托盘中。如果您在选择器中点击同一张照片,它将从托盘中移除。(为代码中的神奇数字道歉;我现在仍在测试)
我在下面附上了一张裁剪过的照片,以了解正确选择了 3 张照片后托盘的外观。
http://dl.dropbox.com/u/762437/screen1.jpg
如果以正常速度点击照片,一切正常。但是,如果用户以某种方式决定以随机方式快速点击照片,它偶尔会弄乱动画和照片在托盘上的位置。
我在下面附上了一个例子。在下面的示例中,实际上只选择了 2 张照片,但不知何故,第 3 张照片仍然部分可见。
http://dl.dropbox.com/u/762437/screen2.jpg
当用户决定只是“捣碎按钮”时,我不确定如何减轻这种行为,可以这么说。
我认为使用 @synchronized(self) 并包装 assetsWasTapped 函数的内部可能会很好,但它似乎没有做任何事情(从主线程调用assetsWasTapped)。
有时,我可能会看到两张照片被添加到托盘中的同一位置,这让我认为我的 NSMutableArray 计数 (selectedPhotos) 存在时间问题,我用它来确定每个缩略图的位置。
对于具体问题,我深表歉意,但也许更通用的版本是如何处理动画和快速用户输入。
任何帮助将不胜感激。谢谢!
- (void)assetWasTapped:(CustomAsset*)tappedAsset
{
// The asset thumbnail was tapped. Check if the count is < 3 and add to the tray
if([selectedAssets count] < 3)
{
NSMutableDictionary *dataToAdd = [NSMutableDictionary dictionaryWithObjectsAndKeys:
tappedAsset, @"selectedAsset",
[[tappedAsset.asset defaultRepresentation] url], @"selectedAssetURL",
tappedAsset.indexPath, @"selectedAssetIndexPath",
[NSNumber numberWithInt:[tappedAsset tag]], @"selectedAssetTag", nil];
[selectedAssets addObject:dataToAdd];
[self addAssetToSelectedTray:tappedAsset];
}
}
- (void)addAssetToSelectedTray:(CustomAsset*)tappedAsset
{
UIView *existingButton;
int xPos = 30;
CustomAsset *tempCustomAsset = [[[CustomAsset alloc] initWithAsset:tappedAsset.asset] autorelease];
// Switch to deal with 1~3 selected assets
switch ([selectedAssets count])
{
case 1:
tempCustomAsset.frame = CGRectMake(125, 8, 73, 73);
[selectedPhotosTray addSubview:tempCustomAsset];
break;
case 2:
for(existingButton in [selectedPhotosTray subviews])
{
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
existingButton.frame = CGRectMake(70, 8, 73, 73);
}
completion:^(BOOL completed){
}
];
}
tempCustomAsset.frame = CGRectMake(180, 8, 73, 73);
[selectedPhotosTray addSubview:tempCustomAsset];
break;
case 3:
for(existingButton in [selectedPhotosTray subviews])
{
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
existingButton.frame = CGRectMake(xPos, 8, 73, 73);
}
completion:^(BOOL completed){
}
];
xPos += 95;
}
tempCustomAsset.frame = CGRectMake(220, 8, 73, 73);
[selectedPhotosTray addSubview:tempCustomAsset];
break;
default:
break;
}
}
- (void)removeAssetFromSelectedTray:(CustomAsset*)tappedAsset
{
// If the asset was removed, remove from the tray
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
tappedAsset.transform = CGAffineTransformMakeScale(0.3, 0.3);
tappedAsset.alpha = 0.0;
}
completion:^(BOOL completed){
[tappedAsset removeFromSuperview];
if([selectedAssets count] == 0)
{
[self closeSelectedPhotosTrayWithAnimation:YES];
}
int xPos = 70;
UIButton *existingButton;
switch ([selectedAssets count])
{
case 1:
for(existingButton in [selectedPhotosTray subviews])
{
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
existingButton.frame = CGRectMake(125, 8, 73, 73);
}
completion:^(BOOL completed){
}
];
}
break;
case 2:
for(existingButton in [selectedPhotosTray subviews])
{
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
existingButton.frame = CGRectMake(xPos, 8, 73, 73);
}
completion:^(BOOL completed){
}
];
xPos += 110;
}
break;
default:
break;
}
}
];
}