0

タップして最大3枚の写真を選択できることを除いて、通常のUIImagePickerControllerと同様のカスタムImagePickerを作成しています。タップして最初の写真を選択すると、小さな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はメインスレッドから呼び出されます)。

トレイの同じ位置に2枚の写真が追加されることがあります。これにより、各サムネイルの配置場所を決定するために使用する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;
                         }
                     }
     ];
}
4

1 に答える 1

1

そのようなことが私に起こったとき、答えはUIViewAnimationOptionBeginFromCurrentStateまたはその名前の付いたものを使用する傾向があります。ここでコードを完成させないでください。

しかし、それはあなたがあなたの道をどのようにやっているかに依存するかもしれません。それが最後の休憩場所を持っているなら、それはそれを修正するはずです。

もう1つの方法は、アニメーションの最初でにを設定してからuserInteractionEnabled、完了ブロックでに設定して、一度に1つのアニメーションのみが実行されるようにすることです。NOYES

于 2012-08-01T14:48:55.093 に答える