2

私が問題を抱えているコードを見たい場合は、ここにリンクがあります: コード

私の質問は私の過去の質問と関連しています。

私は本当に問題を抱えています。NSMutableArray現在iCarouselslotMachineオブジェクト(slot1とslot2)に使用しています。私のアプリは次のように機能します。

サムネイル画像のあるビューを作成し、そのPhotoViewControllerフレームにボタンを割り当てます。したがって、1つの画像が押された場合、。を介してその整数が保存されNSUserDefaultsます。それから私はそれを私の中で取得しますcarouselViewController

アレイの調整を考えていますが、できません。私もここで私の質問を試しました: NSMutableArrayとの比較 私がそれを行うことができれば、Array 2それははるかに簡単ですが、それでも機能しません。

追加情報:)

私はこの方法でそれを行いました。ボタンのあるUIImageViewを含むViewcontrollerがあるので、ユーザーがそれをタップすると、私のCustomPickerポップアップが表示されます。MyCustomPickerには、ユーザーがカメラロールで選択したものの画像が含まれています。したがって、各ボタンには、iCarouselViewusingに送信される特定の値がありますNSUserDefaults。最初のスロットにはcarousel1、2番目のスロットにはcarousel2。

これが私がやりたいことです:ユーザーが選択したインデックスに強制的に停止させたいです。(私は私の中でやっていますcarouselDidEndScrollingAnimtaion

私のcarouselDidEndScrollingAnimation方法では、すべての状態を(個別に)テストしましたが、比較に関しては完全に機能します。次に、条件を組み合わせると、最初の2つの比較またはSTOPは正しいですが、次の2つは常に間違っています。または時々混乱しました。

ユーザーが選択した2つの特定のインデックス/整数をスクロールする必要があります(私はすでにそれを実行しました)がそれらの2つのペアをスクロールできましたが、インデックスが調整されていると思うので、次の2つは常に間違っていました。

ピクチャー:

以下の画像は、私のゲームPhotoViewControllerの比較ステージを含む私のものです。それに応じた番号で入力される.Imageは、強制的に表示され、強制的に表示される必要があります。SETTINGUIImageVIewUIButton

ここに画像の説明を入力してください

私のiCarouselが起動すると、たとえば下の画像で停止します(これは上記と同じではありません): ここに画像の説明を入力してください

入力した画像まで強制的にスクロールしますPhotoViewController

の中へ: ここに画像の説明を入力してください

まとめ: こんな感じ。そこから、 &settingsViewの画像(複数)をインポートします。次に、別のビューで、上の画像が表示されます。最初の列は1番目のスロットに対応し、その後に2番目のスロットが続きます。ビューが押された場合(たとえば、ビューから選択された画像をロードする画像のサムネイルがロードされます。Slot1Slot2PhotoViewControllerNo. 1Slot 1PickerSlot 1

あなたはそれを4回行う必要があります(ペア)---->ここに表示されているのは、ボタン.tagを介してNSUserDefaultsを介してインデックスを取得し、に送信しiCarouselViewます。

次に、完了すると(Doneボタンを押す)、iCarouselView次に進みます。上記のように、そのビューが表示されます。押すと数秒間回転し、終了してもユーザーが選択したPhotoViewところで停止しないと、そのインデックスまで強制的にスクロールします。

質問:

Imを削除するときに、配列またはiCarousel.viewがインデックスを調整しないようにする方法はありますか?インデックスを正しい方法で保持するため。PhotoViewControllerまたは、選択したインデックスも調整するのと同じように、配列を調整するような他の解決策はありますか。配列を削除してもインデックスを保持すると、この問題を解決できると思うからです。しかし、それでもできません。

私の質問を理解していただければ幸いです。

4

5 に答える 5

1

あなたの質問を参照してください。メンバーが配列から削除されたときにメンバーのインデックスを変更しない配列が必要です。

NSMutableDictionaryを使用できると思います。これは、いわば連想配列であり、インデックスは選択可能であり、その間にメンバーを削除してもインデックスは変更されません。インデックスとして0..nを引き続き使用できます。countなど、NSArrayで使い慣れているいくつかのメソッドを引き続き使用できます。列挙子を使用して、辞書のすべてのメンバーを調べることができます。一方、forループは、配列で使用するのに慣れているので、引き続き使用できます。キー/インデックスが存在しない場合(たとえば、削除された場合)、a)objectForKey:iがnilを返す可能性があり、そのカウントはオブジェクトの数を再調整しますが、配列の場合のように最高のインデックス+1は返しません。

于 2012-07-13T08:40:37.753 に答える
1

ここで問題が何であるかを知るのは少し難しいです。画像に単一のNSMutableArrayを使用し、NSUserDefaults値を使用して、配列内のインデックスにあるオブジェクトを取得していますか?

何が起こっているのか100%確信が持てません。ユーザーは何をしますか(そしてどのビューで)、その後何がトリガーされますか(どのビューが表示されますか)。

前のビューから選択したものと同じ画像の「回転」画像を停止しようとしていますか?

上記の画像によると、画像は単一のインデックスでずれています。これは毎回そうですか?配列からのフェッチに問題がある可能性があります。

あなたが私にもう少し情報を与えれば私は助けることができます。

もう一度貼り付けたコードを確認しましたが、これが問題である可能性があります

if (twoSlot1 > [(UIImageView*)[self.carousel2 currentItemView] tag]){            
                [self.carousel1 scrollToItemAtIndex:(-twoSlot1)-2 duration: 3.5f];
            } else {
                [self.carousel1 scrollToItemAtIndex:-twoSlot1 duration: 3.5f];
            }

そのような他のすべてのコードブロックでは、各カルーセルを呼び出す場所にこれがあります。上記のコードでは、カルーセル1を2回呼び出します。

if (slot2 > [(UIImageView*)[self.carousel1 currentItemView] tag]){
            [self.carousel1 scrollToItemAtIndex:(-slot2)-2 duration: 3.0f];
            } else {
            [self.carousel1 scrollToItemAtIndex:-slot2 duration: 3.0f];    
            }

            if (twoSlot2 > [(UIImageView*)[self.carousel2 currentItemView] tag]){
            [self.carousel2 scrollToItemAtIndex:(-twoSlot2)-2 duration: 3.5f];    
            } else {
            [self.carousel2 scrollToItemAtIndex:-twoSlot2 duration: 3.5f];
            }

番号2に電話する必要があるときに、self.carousel1に電話します。

これは正しいです?

于 2012-07-09T17:02:33.043 に答える
1

Imを削除するときに、配列またはiCarousel.viewがインデックスを調整しないようにする方法はありますか?インデックスを正しい方法で保持するため。または、PhotoViewControllerが選択したインデックスを調整するのと同じように、配列を調整するような他の解決策はありますか。配列を削除してもインデックスを保持すると、この問題を解決できると思うからです。しかし、それでもできません。

iCarouselがインデックスを管理する方法を変更する必要がある唯一の方法は、コードを変更することです。実際、removeViewAtIndexiCarousel.mのメソッドを見ると、インデックスがNSDictionaryを介して管理されており、削除した時点で辞書が再配置されていることがわかります(アイテムの順序が変更されています)。あなたはその方法を取ることができます:

- (void)removeViewAtIndex:(NSInteger)index
{
    NSMutableDictionary *newItemViews = [NSMutableDictionary dictionaryWithCapacity:[itemViews count] - 1];
    for (NSNumber *number in [self indexesForVisibleItems])
    {
        NSInteger i = [number integerValue];
        if (i < index)
        {
            [newItemViews setObject:[itemViews objectForKey:number] forKey:number];
        }
        else if (i > index)
        {
            [newItemViews setObject:[itemViews objectForKey:number] forKey:[NSNumber numberWithInteger:i - 1]];
        }
    }
    self.itemViews = newItemViews;
}

同じロジックをアレイに適用して、カルーセルとアレイの同期を維持することができます。もちろん、インデックスをどこかに保存する場合(slot1 / slot2 / slot2 / slot4?)、要素を削除した後にそれらの値も更新する必要があります。

一方、ここで求めているのは、自分が抱えている問題を解決できると信じていることをどうやってやるのかということだと思いますが、実際には問題が何であるかを説明しているわけではありません。確かに、私があなたを正しく理解している場合、あなたがしていることは次のとおりです。

  1. カルーセルを回転させる。

  2. カルーセルが停止したときに、目的のアイテムに偶然にない場合は、そのアイテムまでスクロールするように「強制」します。

一部の要素を削除した後にこれが機能しない理由はありません(iCarouselにいくつかのバグがない限り、解決策はバグをキャッチすることです)。唯一の部分は、どのインデックスに移動したいかを知ることです。

提案として、デリゲートcarouselDidEndScrollingAnimationメソッドを単純化することから始めます。確かに、あなたcarouselDidEndScrollingAnimationにはと呼ばれるパラメータがありますcarousel、まあ、これはあなたがそのメソッドで参照する必要がある唯一のカルーセルだと思います。表示されない場合は、これが理由です。各カルーセルはスクロールを停止し、carouselDidEndScrollingAnimationが呼び出されます。そのため、メソッドは2回呼び出されます。そのメソッドが実行されるたびに、カルーセル1とカルーセル2の両方の状態を変更します(を呼び出すことによってscrollToItemAtIndex)。したがって、各カルーセルでscrollToItemAtIndex2回電話します。

これは私にはあまり正しく聞こえません。carouselDidEndScrollingAnimationしたがって、カルーセル1が呼び出されたときにカルーセル1のみをスクロールし、カルーセル2が呼び出されたときにカルーセル2のみをスクロールする方法を見つける必要がありますcarouselDidEndScrollingAnimation

より一般的に、私が提起したいもう1つのポイントは、次のアイデアです。

  1. カルーセルを停止させる。

  2. もう一度スクロールして、目的の位置に到達します。

ユーザーはカルーセルが停止してから最初からやり直すのを見るので、可能な限り最良の実装ではないようです。

私がこれに取り組む方法は、iCarouselの実装を直接変更して、必要なこの特定の動作をサポートすることです。

具体的には、stepiCarousel.mのメソッドを見てください。これは、カルーセルアニメーションを生成するために、各フレームで呼び出されます。さて、このメソッドにはdeceleratingブランチがあります:

else if (decelerating)
{
    CGFloat time = fminf(scrollDuration, currentTime - startTime);
    CGFloat acceleration = -startVelocity/scrollDuration;
    CGFloat distance = startVelocity * time + 0.5f * acceleration * powf(time, 2.0f);
    scrollOffset = startOffset + distance;

    [self didScroll];
    if (time == (CGFloat)scrollDuration)
    {
        decelerating = NO;
        if ([delegate respondsToSelector:@selector(carouselDidEndDecelerating:)])
        {
            [delegate carouselDidEndDecelerating:self];
        }
        if (scrollToItemBoundary || (scrollOffset - [self clampedOffset:scrollOffset]) != 0.0f)
        {
            if (fabsf(scrollOffset/itemWidth - self.currentItemIndex) < 0.01f)
            {
                //call scroll to trigger events for legacy support reasons
                //even though technically we don't need to scroll at all
                [self scrollToItemAtIndex:self.currentItemIndex duration:0.01];
            }
            else
            {
                [self scrollToItemAtIndex:self.currentItemIndex animated:YES];
            }
        }
        else
        {
            CGFloat difference = (CGFloat)self.currentItemIndex - scrollOffset/itemWidth;
            if (difference > 0.5)
            {
                difference = difference - 1.0f;
            }
            else if (difference < -0.5)
            {
                difference = 1.0 + difference;
            }
            toggleTime = currentTime - MAX_TOGGLE_DURATION * fabsf(difference);
            toggle = fmaxf(-1.0f, fminf(1.0f, -difference));
        }
    }
}

カルーセルの減速が停止すると、カルーセルが再びスクロールされることがわかります。これはあなたがしていることとまったく同じなので、このコードを変更して、カルーセルを必要なインデックスに正確にスクロールさせる方法を見つけるかもしれません。このようにして、カルーセルの回転がはるかにスムーズになります。

これがお役に立てば幸いです。また、長い返信をお詫び申し上げます。

于 2012-07-12T20:30:15.383 に答える
0

私はあなたの全体的な問題を理解するのに苦労していますが、私があなたの質問の核心を集めることができるものからこれはこれです:

Imを削除するときに、配列またはiCarousel.viewがインデックスを調整しないようにする方法はありますか?

それがあなたのより大きな問題を解決するかどうかはわかりませんが、NSMutableDictionaryを使用して配列をシミュレートすると、これを実行できるはずです。ディクショナリのキーとしてインデックスを使用するだけで、インデックスに関連付けられているアイテムを削除しても、結果として他のインデックスは調整されません。例えば:

NSMutableDictionary *arrayDict = [[NSMutableDictionary alloc] init];
[arrayDict setValue:foo forKey:[NSNumber numberWithInt:[arrayDict count]]];
[arrayDict setValue:bar forKey:[NSNumber numberWithInt:[arrayDict count]]];
[arrayDict setValue:fooBar forKey:[NSNumber numberWithInt:[arrayDict count]]];

次に、。を使用してインデックスのオブジェクトにアクセスできます[arrayDict objectForKey:[NSNumber numberWithInt:index]]

setValue:forKey:のキーパラメータにNSNumberを使用すると警告が生成されますが、これは無視しても問題ありません(または、気になる場合は文字列表現を使用してください)。

于 2012-07-13T06:48:41.923 に答える
0

完全に理解できるかどうかはわかりませんが、可変配列内の要素の1つが削除された場合、それを単に削除するのではなく、別の「ダミー」プレースホルダーオブジェクトと一緒に挿入しますか?そうすれば、削除が発生したときにインデックスがまったく変更されません。

于 2012-07-13T15:46:45.280 に答える