2

サブクラス化された 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 

幅に関しては、ある程度役立つようですが、内部のテーブルが適切にレイアウトされていないようです。サイズは正しいように見えますが、回転すると、セルがテーブルをクリップするだけで、回転が適用されていないようにテーブル自体が奇妙に見えます。

4

1 に答える 1

0

部分的な修正:

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;    
    NSArray *paths = [self.collectionView indexPathsForVisibleItems];
    [paths enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UICollectionViewCell *cell =b[self.collectionView cellForItemAtIndexPath:obj];
        [cell.contentView.subviews[0] setFrame:cell.contentView.bounds];
    }];
}

コントローラーをそのメソッドのコレクション ビューのデリゲートとして設定すると、うまくいくように見えますが、Auto Layout を開始して実行してもらいたいと思っています。[cell.contentView setNeedsLayout] / [cell.contentView layoutIfNeeded] は機能しません。

于 2013-03-05T01:05:23.717 に答える