9

UITableViewに非常によく似たカスタムレイアウトのUICollectionViewがあります(垂直方向にスクロールします)。UICollectionViewは、同時に3つのセルのみを表示し、そのうちの1つが現在アクティブなセルです。

[ 1 ]
[*2*]
[ 3 ]

(ここでのアクティブセルは#2です。)セルの高さは約280ポイントであるため、アクティブセルのみが画面に完全に表示されます。ユーザーは、ビューを直接スクロールしてナビゲートするのではなく、アクティブなセルを水平方向にスワイプして次のセルに進みます。次に、いくつかの凝ったアニメーションを実行し、UICollectionViewをスクロールして、次のセルが「アクティブ」の位置になるようにします。これにより、そのセルがアクティブになり、古いセルが移動され、キュー内の次のセルが表示されます。

[ 2 ]
[*3*]
[ 4 ]

ここでの問題は、UICollectionViewのオフセットを設定することです。現在、UIViewアニメーションブロック(self.collectionView.contentOffset = targetOffset;)に他の3つのアニメーションプロパティとともに設定しています。これはほとんどの場合うまく機能しますが、アニメーションが開始するとすぐに最初のセル(以前はアクティブだったセル、後者の場合は#2)が消えます。遅延間隔が完了する前でも実行されます。これは間違いなく理想的ではありません。

私はいくつかの解決策を考えましたが、最良の解決策を見つけることができません:

  1. UICollectionViewのフレームを3つではなく5つのセルに収まるように不条理に拡大して、セルが画面外にある場合でもセルをメモリに保持するように強制します。私はこれを試しましたが、動作しますが、ひどく汚いハックのように聞こえます。

  2. 消えるセルのレンダリングされたコンテンツのスナップショットを取り、それをUIImageViewに配置し、セルが古いセルとまったく同じ位置になくなる直前に、UIImageViewをscrollViewのサブビューとして追加し、アニメーションが終了したら削除します。前のオプションよりも(少なくともメモリに関しては)厄介に聞こえますが、それでもちょっとハッキーです。私もこれを達成するための最良の方法を知りません、正しい方向に私を向けてください。

    1. UIScrollViewに切り替えますsetContentOffset:animated:。私たちは実際にこれを持っていて、セルの消失の問題を修正しましたが、これを他のUIViewアニメーションと並行して実行すると、明らかにメインスレッドの注意を奪い合うため、シングルコアデバイス(iPhone 3GS / 4)。また、アニメーションの長さやイージングを変更できないため、他のアニメーションと同期していないように感じます。UIViewブロックアニメーションと調和して機能させる方法を見つけることができれば、それでもオプションです。

    2. UICollectionViewに切り替えますscrollToItemAtIndexPath:atScrollPosition:animated:。これは試していませんが、大きな欠点があります。ターゲットのスクロール位置に必要な定数は3つだけです(少なくともこの場合に当てはまります) 。 UICollectionViewScrollPositionTop、、UICollectionViewScrollPositionCenteredVerticallyおよびUICollectionViewScrollPositionBottom。アクティブセルはその高さを変えることができますが、常にウィンドウの上部から35ポイントである必要があり、これらのオプションでは、設計を実行するための十分な制御が提供されません。また、3.1と同じくらい問題になる可能性もあります。私が知らないスクロール位置のことを回避する方法があるかもしれないので、それでもオプションです、そしてそれはメインスレッドと同じ問題を持っていないかもしれません、それはありそうもないようです。

どんな助けでも大歓迎です。説明が必要かどうか尋ねてください。どうもありがとう!

4

3 に答える 3

4

私は#2で行きました。レンダリングと保存を行うスニペットは次のとおりです。

UIGraphicsBeginImageContext(theCell.bounds.size);
[theCell.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *renderedCellImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

残りの方法は、上記で説明したとおりでしたが、注意点が1つあります。これは、iPhone 4でレンダリングに最大1秒かかる可能性があるため、画像を実際に使用する前に、バックグラウンドスレッドで実行する必要があります。誰かを助けます。

于 2012-12-01T05:15:26.273 に答える
3

アニメーションブロックでコンテンツオフセットを設定した直後にセルをリロードすることで、セルを表示したままにしました。

UIView.animateWithDuration(0.3) { 
    self.collectionView.contentOffset = newOffset
    self.collectionView.reloadItemsAtIndexPaths(willDisappearIndexPaths)
}
于 2017-01-07T21:56:46.790 に答える
-1

LongShot:UIViewアニメーションブロックオプションをUIViewAnimationOptionBeginFromCurrentStateに設定してみてください。

[UIView animateWithDuration:1
                      delay:0
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{ }
                 completion:^(BOOL  completed){ } ];
于 2012-11-27T23:02:33.337 に答える