web-dev-qa-db-ja.com

UITableViewのtableHeaderViewのようなUICollectionViewにHeaderViewを追加する方法

UICollectionViewの上部にヘッダーセクション/トップビュー(セクションヘッダーではない)を追加するにはどうすればよいですか?

UITableViewtableHeaderViewプロパティとして正確に機能する必要があります。

したがって、最初のセクションヘッダービューの上(インデックス0のセクションの前)に配置し、残りのコンテンツと一緒にスクロールして、ユーザーの操作を行う必要があります。

これまでに思いついた最善の方法は、ファイルの所有者としてMyCollectionReusableViewUICollectionReusableViewサブクラスを使用して)十分な大きさの最初のセクションヘッダービュー用に特別なXIBを作成することです。ヘッダーのサブビューはハックのようなもので、タッチを検出できませんでした。

MyCollectionReusableViewサブクラスを作成してタッチを許可できるか、それとももっと良い方法があるかわかりません。

37
ChrHansen

コレクションビューのサブビューとしてUIViewを追加するだけで、ビューをコレクションビューの上部に配置しました。コレクションビューで上にスクロールし、UIViewの通常のユーザー操作を行います。これは、セクションヘッダーがない場合は問題なく機能しますが、ない場合は機能しません。そのような状況では、私はあなたがそれをしている方法に何の問題もないと思います。なぜタッチが検出されないのかわかりませんが、タッチはうまく機能します。

7
rdelmar
self.collectionView  =  [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 320, self.view.frame.size.height) collectionViewLayout:flowlayout];
self.collectionView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);
UIImageView *imagev = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"015.png"]];
imagev.frame = CGRectMake(0, -50, 320, 50);
[self.collectionView addSubview: imagev];
[self.view addSubview: _collectionView];

属性contentInsetを使用してUICollectionViewの上部にフレームを挿入し、それに画像ビューを追加すると、成功します。 UITableViewtableHeaderViewプロパティとして正確に機能できると思います。どう思いますか?

56
dxci

これを実現する最良の方法は、最初のセクションのセクションヘッダーを作成することです。次に、UICollectionViewFlowLayoutのプロパティを設定します。

@property(nonatomic) BOOL sectionHeadersPinToVisibleBounds

またはスウィフト

var sectionHeadersPinToVisibleBounds: Bool

nO(Swiftの場合はfalse)。これにより、セクションヘッダーがセルと共に継続的にスクロールし、セクションヘッダーが通常のように上部に固定されなくなります。

2
Scott Kaiser

UICollectionViewLayout(UICollectionViewFlowLayout)をサブクラス化し、必要なヘッダーまたはフッター属性を追加するためにこれを実現する最良の方法だと思います。

collectionViewLayoutプロパティに応じたUICollectionViewレイアウトの補足ビューを含むすべてのアイテムなので、ヘッダー(フッター)があるかどうかを決定するのはcollectionviewlayoutです。

contentInsetを使用する方が簡単ですが、ヘッダーを動的に表示または非表示にする場合に問題が発生する可能性があります。

これを実現するためのプロトコルを作成しました。これは、UICollectionViewLayoutの任意のサブクラスで採用して、ヘッダーまたはフッターを持たせることができます。あなたはそれを見つけることができます ここ。

主なアイデアは、ヘッダーのUICollectionViewLayoutAttributesを作成し、必要に応じてlayoutAttributesForElements(in rect: CGRect)に返すことです。他のすべての属性を変更する必要があります。すべての場所はヘッダーによって下に移動する必要がありますヘッダーがすべての上にあるため、高さ。

1
Billthas

最終的に、UICollectionView拡張機能を使用してカスタムヘッダーを追加しました。特定のタグを使用して、保存されたプロパティを偽造してカスタムヘッダーを識別できます(すべて外部から透過)。カスタムヘッダーを追加するときにUICollectionViewのレイアウトが完了していない場合は、特定のオフセットまでスクロールする必要がある場合があります。

extension UICollectionView {
    var currentCustomHeaderView: UIView? {
        return self.viewWithTag(CustomCollectionViewHeaderTag)
    }

    func asssignCustomHeaderView(headerView: UIView, sideMarginInsets: CGFloat = 0) {
        guard self.viewWithTag(CustomCollectionViewHeaderTag) == nil else {
            return
        }
        let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
        headerView.frame = CGRect(x: sideMarginInsets, y: -height + self.contentInset.top, width: self.frame.width - (2 * sideMarginInsets), height: height)
        headerView.tag = CustomCollectionViewHeaderTag
        self.addSubview(headerView)
        self.contentInset = UIEdgeInsets(top: height, left: self.contentInset.left, bottom: self.contentInset.bottom, right: self.contentInset.right)
    }

    func removeCustomHeaderView() {
        if let customHeaderView = self.viewWithTag(CustomCollectionViewHeaderTag) {
            let headerHeight = customHeaderView.frame.height
            customHeaderView.removeFromSuperview()
            self.contentInset = UIEdgeInsets(top: self.contentInset.top - headerHeight, left: self.contentInset.left, bottom: self.contentInset.bottom, right: self.contentInset.right)
        } 
    }
}

CustomCollectionViewHeaderTagは、ヘッダーに付けるタグ番号を参照します。 UICollectionViewに埋め込まれているanotherViewのタグではないことを確認してください。

1
Swift Rabbit