サブクラス化された UICollectionViewFlow レイアウトのコレクション ビューがあります。私が目指している効果は、回転(遠近感、y軸の丸み)と動きのスケールです。私のコレクションビューは、ページングモードがオン、水平スクロール、すべてのセルがフルスクリーンに設定されています。つまり、フレームはコレクションビューの境界と同じです。すべてのセルには、内部にテーブル ビューがあります。
問題は、私が奇妙な振る舞いをしていることです。現在画面に表示されているセル内のテーブルは問題ありません。他のセルにパンすると問題が発生します。セル内のテーブルのサイズが完全に間違っているようです! セルがはるかに大きい場合でも、セルの半分を埋めるだけです。インターフェイスビルダーで、テーブルの端をスーパービュー (セル) の端 (Autolayout) に貼り付けるようにテーブルを設定しました。
しばらくして、ビューがインスタンス化された後、[cell layoutsubviews] が 1 回だけ呼び出されることがわかりました。以下のコードでUICollectionViewLayoutAttributesをすぐに回転させて設定しているので、最初の回転を念頭に置いてテーブルビューをレイアウトできますか(大きなパースペクティブ回転の結果としてスーパービューのフレームが縮小します)、[cell layoutsubiews]は決してもう一度呼び出されてもそのままですか?
2 つ目の奇妙な点は、レイアウトからのコールバックが意味をなさないことです。collectionView:didEndDisplayingCell:forItemAtIndexPath: たとえば、インデックス パスのビューが画面に表示される前に表示されなくなったことがわかります。
誰かがそのレイアウトを試して、何が間違っているのか教えてもらえますか?
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes* attributes in array)
{
if (CGRectIntersectsRect(visibleRect, attributes.frame) &&
ABS(CGRectGetMidX(visibleRect) - attributes.center.x) <= self.collectionView.frame.size.width)
{
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
CGFloat absoluteDistance = ABS(distance);
CGFloat angle = [self normalizeFromMin:0
fromMax:self.collectionView.frame.size.width
toMin:0
toMax:90
value:absoluteDistance];
CGFloat scale = [self normalizeFromMin:0
fromMax:self.collectionView.frame.size.width
toMin:0.7
toMax:1
value:absoluteDistance];
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -1800;
if(distance > 0)
{
transform = CATransform3DRotate(transform, radians(angle), 0.0, 1.0, 0.0);
}
else
{
transform = CATransform3DRotate(transform, -radians(angle), 0.0, 1.0, 0.0);
}
transform = CATransform3DScale(transform, 1.0 - scale, 1.0 - scale, 0.0);
attributes.transform3D = transform;
attributes.alpha = 1.0;
if(distance == 0)
{
attributes.zIndex = 1;
attributes.transform3D = CATransform3DIdentity;
}
else
{
attributes.zIndex = 0;
}
}
}
return array;
}
-(CGFloat)normalizeFromMin:(CGFloat)fromMin
fromMax:(CGFloat)fromMax
toMin:(CGFloat)toMin
toMax:(CGFloat)toMax
value:(CGFloat)toNormalize
{
CGFloat toBeDivided = toMin + (toNormalize - fromMin) * (toMax - toMin);
CGFloat result = toBeDivided / (fromMax - fromMin);
return result;
}
編集:
追加
attributes.frame = attributes.frame
幅に関しては、ある程度役立つようですが、内部のテーブルが適切にレイアウトされていないようです。サイズは正しいように見えますが、回転すると、セルがテーブルをクリップするだけで、回転が適用されていないようにテーブル自体が奇妙に見えます。