所以我采用的解决方案是关闭自动布局(正如 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];
}];
}];
}
}
这使我可以完全控制每种 FlowLayout 子类类型的 Cell 中的每个布局。动画很流畅,我还可以淡出我不希望在特定布局中出现的任何视图。
这样的结果是 UICollectionView,它的行为很像 iPhone Ebay Apps 的网格视图行为,但在我看来更好。
抱歉,我无法粘贴更多代码或将其放在 GitHub 上,因为它来自客户端代码。
不过,我很乐意回答任何问题。
干杯,
布雷特