So the solution I went with was to turn off Auto Layout (as pointed out by Marty), but I also removed all Auto resizing masks too. I created three different hardcoded layouts in the UICollectionViewCell subclass for each UICollectionViewFlowLayout they were going to be displayed in.
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;
}
}
Then when the user selects the cycle layout button I advance to the next layout and call do the following in my ViewController (Has a 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];
}];
}];
}
}
This gives me complete control over each layout in the Cell for each type of FlowLayout subclass. The animations are smooth and I can also fade out any views which I don't want in a particular layout.
The result of this is a UICollectionView which behaves a lot like the iPhone Ebay Apps grid view behaviour, but better in my opinion.
Sorry I can't paste any more code or put it on GitHub as it is from Client Code.
I am happy to answer any questions though.
Cheers,
Brett