2012-08-01 37 views
0

我正在做一個自定義ImagePicker,類似於平常的UIImagePickerController,但您可以點擊選擇最多3張照片。當您點擊選擇第一張照片時,一個小UIView托盤將從底部滑入,並且所選縮略圖將出現在那裏。當您點擊選擇第二張和第三張照片時,它們將被添加到選定的照片紙盒中。如果您在選取器中點擊相同的照片,它將從托盤中移除。 (道歉在代碼中的幻數;我還在測試的東西出來現在)快速用戶輸入搞亂UIViewAnimation

我們已經附上以下裁剪照片給的托盤的外觀與正確選擇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

當這樣的事情發生,我的答案傾向於使用UIViewAnimationOptionBeginFromCurrentState或任何其命名。這裏沒有代碼完成哈哈。

但可能取決於你怎麼做你的路徑。如果它有一個最後的休息場所,那麼它應該修復它。

您可以做的另一件事是在動畫開始時將userInteractionEnabled設置爲NO,然後在完成塊中將其設置回YES,以確保一次只能播放一個動畫。