我正在尝试在各种UICollectionViewFlowLayout子类之间进行动画处理。每个流布局指定不同的项目大小。一个显示一个包含3个项目的网格,另一个显示包含2个项目的网格,第三个显示只有一个项目(看起来像UITableView)。
我正在调用setCollectionViewLayout:animated:来做这件事。单元格大小的动画效果很好。然而,子视图有点混乱。每个单元格都包含一个图像和一个标签(暂时删除了标签)。我希望图像在大小变化时为其大小的变化设置动画,同样也是标签。
如果我使用自动布局(目前还不是很好)来布局我的单元格的子视图,那么在动画开始时,图像会调整为目标单元格框架的大小。我理解UIView动画是如何工作的,因为他们会立即更改动画属性,动画在表示层完成,但我希望自动布局能以某种方式有所不同。
如果我删除自动布局并在initWithFrame中执行以下操作:
[[self imageView] setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin];
然后图像子视图的大小动画很好,但是在循环几个动画后,图像子视图的大小和位置在某些情况下是不正确的。
我已尝试在layoutSubviews中布置子视图,但这会产生与AutoLayout相同的结果。
我在github上看到的所有在UICollectionViewLayouts之间制作动画的演示只有彩色背景或填充整个单元格的子视图。有没有人设法使这个工作?
下面是正在发生的事情的图像(红线是UIImageView的边框):
答案 0 :(得分:39)
要使用AutoLayout,您需要将以下内容放在UICollectionViewCell子类中:
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[UIView animateWithDuration:animationDuration animations:^{
[self layoutIfNeeded];
}];
}
默认动画持续时间约为0.33秒(由实验确定)。
答案 1 :(得分:4)
所以我采用的解决方案是关闭自动布局(正如Marty所指出的那样),但我也删除了所有自动调整大小的蒙版。我在UICollectionViewCell子类中为它们将要显示的每个UICollectionViewFlowLayout创建了三个不同的硬编码布局。
GSProductCollectionViewCell.m
-(void)setLayoutForWideLayoutWithDestinationSize:(CGSize)size
{
[[self imageView] setFrame:CGRectMake( 5.0f, 5.0f, (int)(size.width * 0.3f), size.height - 10.0f)];
[[self titleLabel] setFrame:CGRectMake( self.imageView.right + 5.0f, 5.0f, size.width - self.imageView.right - 15.0f, 25.0f)];
[[self titleLabel] setFont:[UIFont fontWithName:self.titleLabel.font.fontName size:12.0f]];
[[self titleBackgroundView] setFrame:self.titleLabel.frame];
[[self titleBackgroundView] setAlpha:1.0f];
[[self descriptionLabel] setAlpha:1.0f];
[[self descriptionLabel] setFrame:CGRectMake( self.titleLabel.left, self.titleLabel.bottom + 5.0f, self.titleLabel.width, 25.0f)];
[...]
}
-(void)setLayoutForSqaureLayoutWithDestinationSize:(CGSize)size
{
[[self imageView] setFrame:CGRectMake( 5.0f, 5.0f, size.width - 10.0f, size.height - 10.0f - 30.0f)];
[[self titleLabel] setFrame:CGRectMake( 5.0f, size.height - 30.0f, size.width - 10.0f, 25.0f)];
[[self titleLabel] setFont:[UIFont fontWithName:self.titleLabel.font.fontName size:10.0f]];
[[self titleBackgroundView] setFrame:self.titleLabel.frame];
[[self titleBackgroundView] setAlpha:0.0f];
[[self descriptionLabel] setAlpha:0.0f];
[[self descriptionLabel] centerView];
[...]
}
-(void)setLayoutWithFrameSize:(CGSize)size forStyle:(GSProductLayoutStyle)layoutStyle
{
switch (layoutStyle)
{
case kGSProductLayoutStyleGrid3:
case kGSProductLayoutStyleGrid2:
[self setLayoutForSqaureLayoutWithDestinationSize:size];
break;
case kGSProductLayoutStyleList:
[self setLayoutForWideLayoutWithDestinationSize:size];
break;
default:
break;
}
}
然后当用户选择循环布局按钮时,我前进到下一个布局并调用我的ViewController中的以下内容(具有UICollectionView):
-(void)setLayoutStyle:(GSProductLayoutStyle)layoutStyle
{
if (_layoutStyle != layoutStyle)
{
_layoutStyle = layoutStyle;
UICollectionViewFlowLayout *layout;
switch (_layoutStyle)
{
case kGSProductLayoutStyleGrid3:
layout = [GSProductCollectionViewGridLayout new];
break;
case kGSProductLayoutStyleGrid2:
layout = [GSProductCollectionViewGridTwoLayout new];
break;
case kGSProductLayoutStyleList:
layout = [GSProductCollectionViewListLayout new];
break;
default:
layout = [GSProductCollectionViewGridLayout new];
break;
}
CGSize itemSize = layout.itemSize;
[self setCollectionViewLayout:layout animated:YES];
[[self visibleCells] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[(GSProductCollectionViewCell*)obj setLayoutStyle:_layoutStyle];
[UIView animateWithDuration:0.3f animations:^{
[(GSProductCollectionViewCell*)obj setLayoutWithFrameSize:itemSize forStyle:self.layoutStyle];
}];
}];
}
}
这使我可以完全控制Cell中每种类型的FlowLayout子类的每个布局。动画很流畅,我也可以在特定的布局中淡出任何我不想要的视图。
这样做的结果是UICollectionView,其行为与iPhone Ebay Apps网格视图行为非常相似,但在我看来更好。
很抱歉,我无法粘贴任何代码或将其放在GitHub上,因为它来自客户端代码。 我很乐意回答任何问题。
干杯, 布雷特
答案 2 :(得分:1)
你好Brett在找到答案之后我发现这对我有帮助:
UICollectionView cell subviews do not resize
我最终关闭了自动布局,只使用了IB的传统自动调整大小功能。
努力享受!希望它能帮到你!
编辑:抱歉,我刚刚意识到你是以编程方式完成此操作,是否可以在完成块上设置动画集布局中重新加载数据来重绘单元格?按照这个:
UICollectionView cells, auto layout and collectionview layout changes