快速的用户输入弄乱了UIViewAnimation

时间:2012-08-01 14:35:43

标签: iphone uiviewanimation

我正在制作一个自定义的ImagePicker,类似于通常的UIImagePickerController,除了你可以点击选择最多3张照片。当您点击选择第一张照片时,一个小的UIView托盘将从底部滑入,所选的缩略图将出现在那里。当您点击选择第2张和第3张照片时,它们会被添加到所选的照片纸盒中。如果您在选取器中点击相同的照片,它将从托盘中取出。 (对代码中的魔术数字表示道歉;我现在仍在测试中)

我附上了一张裁剪照片,以便了解托盘的外观如何正确选择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;
                         }
                     }
     ];
}

1 个答案:

答案 0 :(得分:1)

当这样的事情发生在我身上时,答案往往是使用UIViewAnimationOptionBeginFromCurrentState或其命名的任何东西。这里没有代码完成哈哈。

但这可能取决于你如何做自己的道路。如果它有一个最后的休息位置那么应该修复它。

您可以做的另一件事是在动画开头将userInteractionEnabled设置为NO,然后在完成块中将其设置回YES以确保只有一个动画一时间去。