Comment append HeaderView dans UICollectionView comme tableHeaderView de UITableView

Comment puis-je append une vue d'en-tête / vue de dessus (et non un en-tête de section) en haut d'un UICollectionView ?

Il devrait agir exactement comme la propriété tableHeaderView .

Il doit donc s'asseoir au-dessus de la première vue d'en-tête de section (avant la section à l'index 0), faire défiler avec le rest du contenu, et avoir l'interaction de l'user.

Le meilleur que j'ai trouvé jusqu'ici est de faire un XIB spécial (avec la sous-class MyCollectionReusableView de UICollectionReusableView tant que propriétaire du file) pour la première vue d'en-tête de section assez grande pour contenir aussi mes sous-vues en entête, c'est une sorte de piratage , Je pense, et je n'ai pas réussi à détecter les touches.

Je ne sais pas si je peux créer ma sous-class MyCollectionReusableView pour autoriser les MyCollectionReusableView ou il existe une meilleure méthode.

    J'ai placé une vue en haut d'une vue de collection en ajoutant simplement un UIView en tant que sous-vue de la vue de la collection. Il fait défiler vers le haut avec la vue de collection et il a une interaction user UIView normale. Cela fonctionne bien si vous n'avez pas d'en-tête de section, mais cela ne fonctionne pas si vous le faites. Dans cette situation, je ne vois rien de mal dans la façon dont vous le faites. Je ne sais pas pourquoi vous ne détectez pas les touches, ils fonctionnent bien pour moi.

     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]; 

    J'utilise l'atsortingbut contentInset pour insert un cadre en haut de l' UICollectionView , puis j'y ajoute la vue de l'image, et cela réussit. Je pense qu'il peut agir exactement comme la propriété tableHeaderView . Qu'est-ce que tu penses?

    La meilleure façon d'y parvenir est de créer un en-tête de section pour la première section. Ensuite, définissez la propriété UICollectionViewFlowLayout:

     @property(nonatomic) BOOL sectionHeadersPinToVisibleBounds 

    ou rapide

     var sectionHeadersPinToVisibleBounds: Bool 

    à NO (faux pour rapide). Cela garantira que l'en-tête de section défile en continu avec les cellules et ne soit pas épinglé au sumt comme le ferait normalement un en-tête de section.

    Je pense que la meilleure façon de le faire est de sous-classr UICollectionViewLayout (UICollectionViewFlowLayout) et d'append les attributes d'en-tête ou de pied de page nécessaires.

    Etant donné que tous les éléments, y compris la vue supplémentaire dans la présentation UICollectionView selon sa propriété collectionViewLayout , c'est la collectionviewlayout viewviewout qui décide s'il existe un en-tête (pied de page) ou non.

    Utilisez contentInset est plus facile, mais il peut y avoir un problème lorsque vous souhaitez masquer ou afficher dynamicment l'en-tête.

    J'ai écrit un protocole pour accomplir ceci, qui pourrait être adopté par n'importe quelle sous-class de UICollectionViewLayout pour lui donner un en-tête ou un pied de page. Vous pouvez le find ici.

    L'idée principale est de créer un UICollectionViewLayoutAtsortingbutes pour l'en-tête et le returnner dans layoutAtsortingbutesForElements(in rect: CGRect) si nécessaire, vous devrez modifier tous les autres attributes, tous leurs locations doivent être déplacés par hauteur d'en-tête car l'en-tête est au-dessus d'eux tous.

     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, atsortingbute: .leading, relatedBy: .equal, toItem: view, atsortingbute: .leading, multiplier: 1.0, constant: 0) let widthConstraint = NSLayoutConstraint(item: self, atsortingbute: .width, relatedBy: .equal, toItem: nil, atsortingbute: .notAnAtsortingbute, multiplier: 1.0, constant: view.frame.size.width) let heightConstraint = NSLayoutConstraint(item: self, atsortingbute: .height, relatedBy: .equal, toItem: nil, atsortingbute: .notAnAtsortingbute, multiplier: 1.0, constant: view.frame.size.height) let topConstraint = NSLayoutConstraint(item: self, atsortingbute: .top, relatedBy: .equal, toItem: view, atsortingbute: .top, multiplier: 1.0, constant: 0) view.addConstraints([leftConstraint, widthConstraint, heightConstraint, topConstraint]) self.layoutIfNeeded() view.layoutIfNeeded() } }