解決しました。
少しだけレイアウトを微調整するだけでよかったので、UICollectionViewFlowLayout のサブクラスを使用することにしました。このようにして、必要に応じてレイアウトを「再生」したり、ヘッダー/フッターのフレームを変更したりできます。
私のソリューションは次のように機能します:
.h
@interface MyUICollectionViewFlowLayout : UICollectionViewFlowLayout
@end
.m
#define HEADER_VIEW_WIDTH 132
#define HEADER_VIEW_HEIGHT 44
@interface MyUICollectionViewFlowLayout ()
@end
@implementation MyUICollectionViewFlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
for (UICollectionViewLayoutAttributes *attribute in allAttributes) {
// if it's a cell, change it's layout to be right after the Header, and in the same line.
if (attribute.representedElementCategory == UICollectionElementCategoryCell) {
switch (attribute.indexPath.row) {
case 0:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH, 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 1:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 2:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width * 2 , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 3:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width * 3 , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 4:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width * 4 , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 5:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width * 5 , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
case 6:
attribute.frame = CGRectMake(HEADER_VIEW_WIDTH + attribute.frame.size.width * 6 , 0, attribute.frame.size.width, attribute.frame.size.height);
break;
// if it's a header view, move it to the same line as all the cells.
} else if (attribute.representedElementCategory == UICollectionElementCategorySupplementaryView){
attribute.frame = CGRectMake(0, 0 , HEADER_VIEW_WIDTH, HEADER_VIEW_HEIGHT);
}
}
return allAttributes;
}
@end
スイッチ/ケースの代わりに、アルゴリズムを書くこともできたと思いますが、最適化の問題は後で残しておきます。