ios UICollectionView 和自定义 UICollectionReusableView 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16579740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UICollectionView & custom UICollectionReusableView not works
提问by Romowski
I'm trying to use custom UICollectionReusableView
(which has own class and XIB) in my UICollectionView
header. But after fetching data in the place of header I have nothing.
我试图UICollectionReusableView
在我的UICollectionView
标题中使用自定义(它有自己的类和 XIB)。但是在标题的位置获取数据后,我什么都没有。
My steps:
我的步骤:
Registering class in viewDidLoad:
[self.collectionView registerClass:[CollectionViewHeader class] forSupplementaryViewOfKind: UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"];
Trying to show:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionReusableView *reusableView = nil; if (kind == UICollectionElementKindSectionHeader) { CollectionViewHeader *collectionHeader = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath]; NSInteger section = [indexPath section]; id <NSFetchedResultsSectionInfo> sectionInfo = [fetchRecipes sections][section]; collectionHeader.headerLabel.text = @"bla-bla-bla"; reusableView = collectionHeader; } return reusableView; }
在viewDidLoad 中注册类:
[self.collectionView registerClass:[CollectionViewHeader class] forSupplementaryViewOfKind: UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"];
试图显示:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionReusableView *reusableView = nil; if (kind == UICollectionElementKindSectionHeader) { CollectionViewHeader *collectionHeader = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath]; NSInteger section = [indexPath section]; id <NSFetchedResultsSectionInfo> sectionInfo = [fetchRecipes sections][section]; collectionHeader.headerLabel.text = @"bla-bla-bla"; reusableView = collectionHeader; } return reusableView; }
Can anybody tell me what's wrong? ) Thanks for any advice
谁能告诉我出了什么问题?) 感谢您的任何建议
回答by Anil Varghese
I think you are adding label to the xib. So you need to registerNib:for the header view instead of registerClass:
我认为您正在向 xib 添加标签。所以你需要registerNib:对于标题视图而不是registerClass:
回答by andrewoodleyjr
Register Your header nib/xib in the viewDidLoad section.
[self.collectionView registerNib: [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"headerCell"];
Create the custom supplementary view cell.
- (headerCollectionViewCell *)collectionView:(UICollectionView *)collectionViews viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionReusableView *reusableView = nil; if (kind == UICollectionElementKindSectionHeader) { UINib *nib = [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil]; [collectionViews registerNib:nib forCellWithReuseIdentifier:@"headerCell"]; headerCollectionViewCell *collectionHeader = [collectionViews dequeueReusableCellWithReuseIdentifier:@"headerCell" forIndexPath:indexPath]; collectionHeader.titleLabel.text = @"What"; reusableView = collectionHeader; } return reusableView; }
在 viewDidLoad 部分注册您的头 nib/xib。
[self.collectionView registerNib: [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"headerCell"];
创建自定义补充视图单元格。
- (headerCollectionViewCell *)collectionView:(UICollectionView *)collectionViews viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionReusableView *reusableView = nil; if (kind == UICollectionElementKindSectionHeader) { UINib *nib = [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil]; [collectionViews registerNib:nib forCellWithReuseIdentifier:@"headerCell"]; headerCollectionViewCell *collectionHeader = [collectionViews dequeueReusableCellWithReuseIdentifier:@"headerCell" forIndexPath:indexPath]; collectionHeader.titleLabel.text = @"What"; reusableView = collectionHeader; } return reusableView; }
回答by Zanael
class CustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
for attributes in attributesForElementsInRect! {
if !(attributes.representedElementKind == UICollectionElementKindSectionHeader
|| attributes.representedElementKind == UICollectionElementKindSectionFooter) {
// cells will be customise here, but Header and Footer will have layout without changes.
}
newAttributesForElementsInRect.append(attributes)
}
return newAttributesForElementsInRect
}
}
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let headerNib = UINib.init(nibName: "HeaderCell", bundle: nil)
collectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")
let footerNib = UINib.init(nibName: "FooterCell", bundle: nil)
collectionView.register(footerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "FooterCell")
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! FooterCell
return footerView
default:
return UICollectionReusableView()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 45)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 25)
}
}
回答by timurbeg
Just in case if someone needs solution. You don't have to register the header class using
以防万一有人需要解决方案。您不必使用注册头类
[self.collectionView registerClass:...]
Just use the layout's delegate method to return the header class.
只需使用布局的委托方法返回头类。
回答by gbk
Actually there is can be few reasons:
其实可能有以下几个原因:
(most common) If u add u'r
suplementaryView
in storyboard, and then try to register class[self.stickyCollectionView registerClass:[<CLASSFORSUPPLEMENTARYVIEWW> class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([<CLASSFORSUPPLEMENTARYVIEWW> class])];
(最常见)如果你
suplementaryView
在故事板中添加你,然后尝试注册类[self.stickyCollectionView registerClass:[<CLASSFORSUPPLEMENTARYVIEWW> class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([<CLASSFORSUPPLEMENTARYVIEWW> class])];
u will get suplementaryView
, but not that u create (standard one) - u will see obj, but actually this is will be like placeholder.
你会得到suplementaryView
,但不是你创造的(标准的) - 你会看到 obj,但实际上这就像占位符。
Example:
例子:
Here u can see that obj was created, but outlets are nil (in this simple case only one outlet - _monthNameLabel
).
在这里您可以看到 obj 已创建,但出口为零(在这种简单的情况下只有一个出口 - _monthNameLabel
)。
- I see few times this problem also
- 我也看到几次这个问题
If u create separate Obj
for handling dataSourse/delegate for collectionView
and add reference outlet to it, and in init
methods try to register class to u'r outlet (assumed that view created in separate nib file), u will also receive same result like previous, but reason another - u'r outlet is nil here:
如果您创建单独的Obj
用于处理数据源/委托collectionView
并为其添加引用插座,并且在init
方法中尝试将类注册到您的插座(假设在单独的 nib 文件中创建的视图),您也将收到与以前相同的结果,但是另一个原因 - 你的出口在这里为零:
As solution u for example can use custom setter for this like:
例如,作为解决方案,您可以使用自定义设置器,例如:
#pragma mark - CustomAccessors
- (void)setcCollectionView:(UICollectionView *)collectionView
{
_collectionView = collectionView;
[self.stickyCollectionView registerNib:...];
}
- as suggested by @Anil Varghese
- 正如@Anil Varghese 所建议的
u can use registerClass
instead of registerNib
你可以用registerClass
代替registerNib
回答by Hyman
Xcode 9, Swift 4:
Xcode 9,斯威夫特 4:
Register UICollectionReusableView
in viewDidLoad
注册UICollectionReusableView
在viewDidLoad
self.collectionView.register(UINib(nibName: "DashBoardCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "ReuseIdentifier")
回答by 93sauu
You was registering correctly the class and the delegate is implemented correctly.
您正确注册了课程并且正确实现了委托。
The problem can be that the flow layout (by default) is not configured for header view, do you have this line in the code or interface file?
问题可能是流布局(默认情况下)没有为标题视图配置,你的代码或界面文件中有这行吗?
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)_collectionView.collectionViewLayout;
flowLayout.headerReferenceSize = CGSizeMake(CGRectGetWidth(_collectionView.bounds), 100);