Пользовательская проблема UICollectionViewFlowLayout

У меня есть представление коллекции с подклассом макета UICollectionViewFlow. Эффект, к которому я стремлюсь, - это вращение (перспектива, вокруг оси Y) и масштабирование при движении. В представлении «Моя коллекция» включен режим постраничного просмотра, горизонтальная прокрутка, каждая ячейка имеет полноэкранный режим, то есть их рамка равна границам представления коллекции. Каждая ячейка имеет табличное представление внутри.

Проблема в том, что я получаю странное поведение. Таблица внутри ячейки, которая в данный момент находится на экране, в порядке. Проблема возникает, когда я перемещаюсь к другой ячейке. Таблица внутри ячейки, кажется, имеет совершенно неправильный размер! Он просто заполняет половину ячейки, хотя ячейка намного больше. В построителе интерфейса я настроил таблицу так, чтобы ее края прикреплялись к краям ее супервидов (ячеек) (автомакет).

Через некоторое время я понял, что [cell layoutsubviews] вызывается только один раз после создания экземпляра представления. Поскольку я устанавливаю UICollectionViewLayoutAttributes с вращением сразу в этом коде ниже, может ли табличное представление быть выложено с учетом начального вращения (кадр суперпредставления сжимается в результате сильного вращения перспективы), и поскольку [cell layoutsubiews] никогда не позвонил снова, он просто остается таким?

Вторая странность заключается в том, что обратные вызовы из макета не имеют смысла. 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 

Кажется, это помогает с точки зрения ширины, но таблица внутри не выглядит правильно. Похоже, что размер правильный, но при вращении ячейка просто обрезает таблицу, но сама таблица выглядит странно, как будто к ней не было применено вращение,


person foFox    schedule 05.03.2013    source источник


Ответы (1)


Частичное исправление:

- (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] не работают.

person foFox    schedule 05.03.2013