47

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

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

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

私がこれまでに思いついた最善の方法は、最初のセクションのヘッダービュー用に特別なXIB(ファイルの所有者としてのMyCollectionReusableViewサブクラスを使用UICollectionReusableView)を作成することです。これは、ヘッダーにサブビューを含めるのに十分な大きさです。これは一種のハックです。考えてみてください、そして私はタッチを検出することができませんでした。

MyCollectionReusableViewサブクラスを作成してタッチを許可できるかどうか、またはより良い方法があるかどうかはわかりません。

4

7 に答える 7

62
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それに画像ビューを追加すると、成功します。まさにその財産として機能できると思いUITableViewますtableHeaderView。どう思いますか?

于 2013-08-02T11:31:53.803 に答える
10

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

于 2012-11-23T05:38:10.800 に答える
6

iOS 13以降、ヘッダーを設定するための標準的な方法は、UICollectionViewCompositionalLayoutConfiguration

このようboundarySupplementaryItemsにして、セクションごとに、またはコレクションビューに対してグローバルに設定できます。

let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))

let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "header", alignment: .top)

let config = NSCollectionViewCompositionalLayoutConfiguration()
config.boundarySupplementaryItems = [header]

let layout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider, configuration: config)

return layout

詳細については、 https://developer.apple.com/documentation/appkit/nscollectionviewcompositionallayoutconfigurationの公式ドキュメントをご覧ください。

于 2021-02-06T13:04:41.327 に答える
5

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のタグではないことを確認してください。

于 2018-03-02T21:08:50.717 に答える
2

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

@property(nonatomic) BOOL sectionHeadersPinToVisibleBounds

または迅速

var sectionHeadersPinToVisibleBounds: Bool

NO(スイフトの場合はfalse)。これにより、セクションヘッダーがセルとともに連続的にスクロールし、セクションヘッダーが通常行うように上部に固定されないようになります。

于 2016-01-06T06:32:21.683 に答える
1

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

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

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

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

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

于 2017-09-01T02:35:14.390 に答える
-2
private var PreviousInsetKey: Void?
extension UIView {

var previousInset:CGFloat {
    get {
        return objc_getAssociatedObject(self, &PreviousInsetKey) as? CGFloat ?? 0.0
    }
    set {
        if newValue == -1{
            objc_setAssociatedObject(self, &PreviousInsetKey, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        else{
            objc_setAssociatedObject(self, &PreviousInsetKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}


func addOnCollectionView(cv: UICollectionView){
    if self.superview == nil{
        var frame = self.frame
        frame.size.width = SCREEN_WIDTH
        cv.frame = frame
        self.addOnView(view: cv)
        let flow = cv.collectionViewLayout as! UICollectionViewFlowLayout
        var inset = flow.sectionInset
        previousInset = inset.top
        inset.top = frame.size.height
        flow.sectionInset = inset
    }

}

func removeFromCollectionView(cv: UICollectionView){
    if self.superview == nil{
        return
    }
    self.removeFromSuperview()
    let flow = cv.collectionViewLayout as! UICollectionViewFlowLayout
    var inset = flow.sectionInset
    inset.top = previousInset
    flow.sectionInset = inset
    previousInset = -1
}

func addOnView(view: UIView){

    view.addSubview(self)

    self.translatesAutoresizingMaskIntoConstraints = false
    let leftConstraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0)
    let widthConstraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.size.width)
    let heightConstraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: view.frame.size.height)
    let topConstraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0)

    view.addConstraints([leftConstraint, widthConstraint, heightConstraint, topConstraint])
    self.layoutIfNeeded()
    view.layoutIfNeeded()
}
}
于 2017-06-06T09:42:34.750 に答える