未调用 UICollectionReusableView 方法

我希望我的部分在 UICollectionView有一个头与图像。

我遵循以下步骤:

  • 在故事板上,分配了一个头作为我的 UICollectionView的配件
  • 给了它一个标识符
  • 为它创建了一个 UICollectionReusableView子类
  • 在情节串连图板上将自定义类分配给该类。
  • ImageView放在标题附件上
  • .h文件的自定义类中为 ImageView设置了一个出口
  • viewDidLoad会议上实施了以下措施:

[self.collectionView registerClass:[ScheduleHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier];


-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *reusableview = nil;


if (kind == UICollectionElementKindSectionHeader)
{
ScheduleHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier forIndexPath:indexPath];


headerView.headerImageView.image = [UIImage imageNamed:@"blah.png"];


reusableview = headerView;
}


return reusableview;
}

我知道数据源和委托方法正在工作,因为我可以看到所有的单元格及其部分。但是,我没有头。我在上面的方法中放入了一个断点,它从未被调用过。

我做错了什么?

54571 次浏览

It seems that you have to give your header a non-zero size or collectionView:viewForSupplementaryElementOfKind:atIndexPath isn't called. So either set the headerReferenceSize property of the flow layout like so:

flowLayout.headerReferenceSize = CGSizeMake(self.collectionView.frame.size.width, 100.f);

Swift 5+

flowLayout.headerReferenceSize = CGSize(CGSize(width: self.collectionView.frame.size.width, height: 100))

or, implement collectionView:layout:referenceSizeForHeaderInSection if you want to vary the size by section.

You answered the question, but in words I understand better:

To make the method being called, add these methods:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake(60.0f, 30.0f);
}


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
return CGSizeMake(60.0f, 30.0f);
}

...and go from there.

Did you add UICollectionViewDelegateFlowLayout in current interface? This worked for me.

@interface MyViewController () <UICollectionViewDelegateFlowLayout>

Swift:

class MyViewController: UICollectionViewDelegateFlowLayout {

There is the swift version :

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
let size = CGSize(width: 400, height: 50)
return size
}


func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
let size = CGSize(width: 400, height: 50)
return size
}

XCode (version 7.3.1 ) does not propose these methods in autocomplete !

If you just want a header, just keep the header method.

Swift 3.0 (xcode 8.2.1)

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width:collectionView.frame.size.width, height:30.0)
}

My problem was that in swift 3, the name of the viewForSupplementaryElementOfKind function has changed slightly from any posts that were on stack overflow. Hence, it was never getting called. Make sure that, if you're in swift 3, you're delegate function matches:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {}

Swift 4 Xcode 9.1 Beta 2

Add @objc

@objc func collectionView(_ collectionView: UICollectionView, layout  collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize{
let size = CGSize(width: 400, height: 50)
return size
}

Credits: https://medium.com/@zonble/your-delegation-methods-might-not-be-called-in-swift-3-c6065ed7b4cd

I have the same issue. I have added referenceSizeForFooterInSection but then also viewForSupplementaryElementOfKind not getting called. I have added this code in viewDidLoad() and it worked for me:

if let flowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.sectionFootersPinToVisibleBounds = true
}

For me, in Swift 4.2, func collectionView(collectionView:kind:indexPath:) -> UICollectionReusableView was never being called. This was for a collection view in a UIViewController. I noticed the existing collection view functions were qualified with @objc, and that the UICollectionView had not adopted the UICollectionViewDataSource and UICollectionViewDelegate protocols. As soon as I adopted the protocols, I got errors that the collection view functions did not match the protocol. I corrected the function syntax, removed the qualifiers, and the section headers started working.

    @objc (collectionView:viewForSupplementaryElementOfKind:atIndexPath:)
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { }

The above code worked for me

If you've got a generic subclass then you must take care to specify ObjC delegate method name if it's different then Swift name (https://bugs.swift.org/browse/SR-2817).

@objc (collectionView:viewForSupplementaryElementOfKind:atIndexPath:)
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
...

Swift 5 Smooth and easy way

only these two line are missing in your code and you will done

use these line any where

let layout = self.colv.collectionViewLayout as! UICollectionViewFlowLayout
layout.headerReferenceSize = CGSize(width: self.colv.frame.size.width, height: 100)

I am using these lines in

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let CellCount = CGFloat(3.0)
let width = CGFloat(collectionView.frame.size.width/CellCount)
//let height = CGFloat(collectionView.frame.size.height)


    

let layout = self.colv.collectionViewLayout as! UICollectionViewFlowLayout


layout.headerReferenceSize = CGSize(width: self.colv.frame.size.width, height: 100)
    

return CGSize(width: width, height: width+10)
}