2013-07-20 32 views
20

UICollectionViewの項目をアニメーション表示して、ユーザーがリストをスクロールするときに表示します(私はUICollectionViewFlowLayoutのサブクラスを使用しています)。UICollectionVIew:セルがスクロールしてアニメーション表示される

レイアウトマネージャで位置を指定していますが、最初の変換を指定して、それが正しい時刻(セルが最初に画面に表示されるとき)にアニメーションに適用することができます。効果を確認するには、iOSでGoogle Plusアプリをチェックしてください。理想的には、セルの位置に応じて異なる変換を行います。

セルがいつ表示されるかを知る方法が見つからないようです(にあるwillDisplayCellの同等物もありません)。

提案がありますか?

あなたはちょうど約このスクリーンショットは、Google Plusでアニメーションを作ることができます、また Example in the Google Plus App

iPad上のiPhotoを見てみましょう。 UIcollectionViewを使用しているかどうかはわかりませんが(おそらくiOS5ではうまくいきませんでしたが)、これは、私が探している効果であれば、写真は右から飛んでいるようです。

+0

ちょっとuはそのための答えを得ることになったのですか?私は同じ動作を実装しようとしている、あなたの助けに感謝します。 –

+0

いいえ、ごめんなさい - 私は標準のスクロールビューを使用して終了しました。 – Marc

+0

@JackKapow、私は便利かもしれない以下の答えを掲載しました。私はおそらくしばらくの間、これをテストする機会を持っているので、あなたはこれを試してみて、それが動作するかどうか、私はここで知っていると私は受け入れ答えとしてそれをマークしますしません@JackKapow – Cezar

答えて

36

この効果は、カスタムレイアウトとは別に実現できます。セルがデキューされると、アニメーションのコードがcollectionView:cellForItemAtIndexPath:

の内側に行くべき

、そのframeはあなたのレイアウトで指定されたものに設定されます。セルの最後のframeとして一時変数に格納することができます。 cell.frameを画面外の初期位置に設定してから、最終的な位置に向かってアニメートすることができます。線に沿って何か:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; 

    CGRect finalCellFrame = cell.frame; 
    //check the scrolling direction to verify from which side of the screen the cell should come. 
    CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview]; 
    if (translation.x > 0) { 
     cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0); 
    } else { 
     cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0); 
    } 

    [UIView animateWithDuration:0.5f animations:^(void){ 
     cell.frame = finalCellFrame; 
    }]; 

    return cell; 
} 

上記のコードは、スクロール方向に応じて、いずれかの側から、画面の上部から来る水平UICollectionViewに細胞をアニメートします。現在のindexPathをチェックして、より複雑なレイアウト上の異なる位置からアニメーション化したり、フレームとともに他のプロパティをアニメーション化したり、トランスフォームを適用したりすることもできます。マルクは彼が私には、標準のテーブルビューでそれを行う方法を示したいスクロールビューを使用して終了することを、コメントで述べたように

+0

ちょっと、ちょっと!ありがとう!私はそれと少し演奏し、今のところそれは素晴らしいよ!何か問題が見つかったら教えてあげるよ、ありがとう! –

+0

一度しかアニメーション化されないようにする方法はありますか?私は、私はそれをアニメーション化する初めてスクロールダウンしたときに私が意味する - そして私は –

+2

(正確にグーグル+のように)唯一の新しい細胞がアニメーション化したい、私はあなたが何を意味するか知っています。 Google +では、新しいコンテンツがCollectionViewデータソースに挿入されたときにアニメーション化されている可能性があります。スクロール時に再びアニメーション化するのを防ぐために、一連のフラグを格納し、アニメーション化された各indexPathに対してその値を設定する必要があると思います。指定されたindexPathのためにセルをデキューするときは、その配列をチェックして、アニメーション化する必要があるかどうかを確認します。 – Cezar

6

コレクションビューレイアウトでinitialLayoutAttributesForAppearingItemAtIndexPath:を上書きする必要があります。ここでは、セルが出現した後に実際の属性にアニメートされるレイアウト属性項目(変換を含む)の任意の属性を設定できます。

標準のレイアウト属性オブジェクトで十分なオプションが得られない場合は、セルをサブクラス化して余分な属性を追加し、applyLayoutAttributes:をオーバーライドして追加のプロパティを取得できます。

これは、コレクションビューにセルを追加する場合にのみ機能します。

コレクションビューをスクロールダウンするときにセルに変換を適用するには、セルに直接適用するか(cellForItem ...)、レイアウト属性で、おそらくinitialTransformというプロパティを適用します。セルにレイアウト属性を適用する場合は、initialTransformをチェックして適用し、それをIDに設定してから、アニメーションをトリガしてIDトランスフォームに移動します。これにより、セルが最初にスクロールされたときにのみ適用されます画面。このようなことは何も実装していません。私はそれをどうやって行うのかというだけの推測です。

+0

ここでブレークポイントを設定すると、画面が回転するときにだけ呼び出されます。ヘッダーのコメントはこれもこれを示すようです。設定が必要なものはありますか? 私はUICollectionViewFlowLayoutをサブクラス化しています。 – Marc

+0

アイテムをビューに追加するとき、またはスクロールするときに呼び出される必要があります。 – jrturton

+2

ドキュメントによれば、このメソッドはデータが変更されたとき、またはスクロールするときではなくコレクションビューを再描画する必要があるときに呼び出されます。スクロールするとこのコールバックが発せられるのを確認できますか? 引用符 **コレクションビューのデータが変更され、アイテムが挿入または削除されると、コレクションビューはそのレイアウトオブジェクトにレイアウト情報の更新を要求します。** " http://developer.apple.comから。 COM /ライブラリ/ IOS /ドキュメント/ UIKitの/参照/ UICollectionViewLayout_class /リファレンス/のreference.html – Marc

3

。 Google +に見られるのと同じ効果ではありませんが、簡単に適応できます。セルは、各セルに、我々は以前の設定にそれをバックアニメーションよりも我々はオフセット(およびおそらくは回転)を割り当て表示されている直前

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static CGFloat duration = .5; 
    static NSUInteger xOffset = 50; 
    static NSUInteger yOffset = 200; 
    if(scrollDirection == STAScrollDirectionDown && lastAnimatedIndex < indexPath.row) 
    { 
     cell.frame = CGRectMake(cell.frame.origin.x - xOffset, cell.frame.origin.y+yOffset, cell.frame.size.width, cell.frame.size.height); 
     [UIView animateWithDuration:duration 
         animations:^{ 
      cell.frame = CGRectMake(cell.frame.origin.x + xOffset, cell.frame.origin.y - yOffset, cell.frame.size.width, cell.frame.size.height); 
     } completion:^(BOOL finished) { 
      lastAnimatedIndex = indexPath.row; 
     }]; 
    } 
} 


もう少し刺激的な例:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    CATransform3D rotation = CATransform3DMakeRotation((90.0*M_PI)/180, .0, 0.5, 0.5); 
    cell.contentView.alpha = 0.8; 
    cell.contentView.layer.transform = rotation; 
    cell.contentView.layer.anchorPoint = CGPointMake(0, 0.5); 

    [UIView animateWithDuration:.5 
        animations:^{ 
         cell.contentView.layer.transform = CATransform3DIdentity; 
         cell.contentView.alpha = 1; 
         cell.contentView.layer.shadowOffset = CGSizeMake(0, 0); 
        } completion:^(BOOL finished) { 
        }]; 
} 
+0

私はちょうどこの画像をチェックし、viewWillAppearと名前を混同 'cellWillAppear' – vikingosegundo

+0

申し訳I」意味cellWillDisplayを認識していないです:http://postimg.org/image/a2g02xgbl/ – Chlebta

+0

は、新しい質問を作成し、あなたのコードを投稿あなたが何を達成したいのか、何を見ているのかを記述します。 – vikingosegundo

関連する問題