web-dev-qa-db-ja.com

iOS UICollectionViewを使用して特定のセクションのみにヘッダービューを許可する

以下のコードはヘッダービューを正しく表示しますが、UICollectionViewの各セクションに対して:

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
          viewForSupplementaryElementOfKind:(NSString *)kind
                                atIndexPath:(NSIndexPath *)indexPath {
    UICollectionReusableView * headerView =
        [collectionView 
            dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader 
                               withReuseIdentifier:@"SectionHeaderCollectionReusableView"
                                      forIndexPath:indexPath];
    switch (indexPath.section) {
        case Section_One:
            return headerView;
        case Section_Two:
            return headerView;
        case Section_Three:
            return headerView;
        case Section_Four:
            return headerView;
        case Section_Five:
            return headerView;

        default:
            return headerView;
    }
}

代わりにやりたいことは、「Section_One」または「Section_Two」のヘッダービューを表示しないことですが、「nil」を返すと「NSInternalInconsistencyException」になります。

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
          viewForSupplementaryElementOfKind:(NSString *)kind
                                atIndexPath:(NSIndexPath *)indexPath {
    UICollectionReusableView * headerView =
        [collectionView 
            dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader 
                               withReuseIdentifier:@"SectionHeaderCollectionReusableView"
                                      forIndexPath:indexPath];
    switch (indexPath.section) {
        case Section_One:
            return nil;
        case Section_Two:
            return nil;
        case Section_Three:
            return headerView;
        case Section_Four:
            return headerView;
        case Section_Five:
            return headerView;

        default:
            return nil;
    }
}

特定のセクションのみのヘッダービューを表示するにはどうすればよいですか?

29
Gifreakius

先に進み、各セクションのヘッダーを返し、このUICollectionViewDelegate関数でセクションヘッダーのサイズをゼロのサイズに設定します。

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return CGSizeZero;
    }else {
        return CGSizeMake(self.collectionView.bounds.size.width, desiredHeight);
    }
}
55
mwright

1つのUICollectionViewControllerが2つのUICollectionViews(後でコレクションビュー1および2として参照)を制御するケースがあり、2番目のヘッダー(またはフッター)にはヘッダーが必要でした。

@mwrightの答えに欠けているのは、次のようにcollection view 2に対してCGSizeZeroを返すときです。

_func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if collectionView == self.collectionView2 {
        return CGSizeZero
    }
    return < something else >
}
_

...はcollectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableViewdoes notcollection view 2に対して呼び出されることを意味します。

つまり、2番目のコレクションビューに「間違った」ヘッダーを返すことを心配する必要はありません。

7

再利用可能なヘッダーのXIBでAutoLayoutを使用すると、が受け入れられた回答が壊れたに気付きました。

コンテンツを端から離したり、ヘッダービュー内のアイテムに静的で不変のサイズを与えたりすると、特に壊れていました。ヘッダーサイズをCGSizeZeroに設定すると、デリゲートメソッドで設定された要件を満たすためにすべての制約が解除されるというInterface Builderからの警告が多数表示され、デバッガコンソールが乱雑になりました。

それ自体は技術的に災害ではありませんが、まだ汚いです。また、SwiftおよびAutoLayoutの時代には、よりクリーンなソリューションが必要になります。また、仕事中にそのようなものをクライアントに出荷したくないこともあります。

これを修正するには、referenceSizeForHeaderInSection:を呼び出してCGSizeZeroを返す代わりに、XIBでUICollectionReusableViewの別のサブクラスを作成し、その内部のビューの高さを0に設定しました。

その後、switchメソッド内に含まれるviewForSupplementaryElementOfKindステートメントの外側でそのバリアントをデキューします。これは、Interface Builderの両方の視覚的要件を満たします! ????

とにかく、デバッグ中にコンソールに何百もの不満足な制約警告が出力されてしまう。

4
topLayoutGuide

**

サイズ(0、0)の値を返す場合、ヘッダーは追加されません。

**

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

 switch section {
 case 0:
   return CGSize(width: collectionView.bounds.width, height: 70)
 case 1:
   return CGSize(width: 0, height: 0) // NO HEADER WILL BE ADDED
 case 2:
   return CGSize(width: collectionView.bounds.width, height: 70)
 case 3:
   return CGSize(width: 0, height: 0) // NO HEADER WILL BE ADDED
 default:
   return CGSize(width: collectionView.bounds.width, height: 70)
 }

}
2