У меня есть представление коллекции с подклассом макета 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
Кажется, это помогает с точки зрения ширины, но таблица внутри не выглядит правильно. Похоже, что размер правильный, но при вращении ячейка просто обрезает таблицу, но сама таблица выглядит странно, как будто к ней не было применено вращение,