Ken*_*eld 11 ios uicollectionview uicollectionviewlayout ios7
我试图在UICollectionView
使用子UICollectionViewFlowLayout
类的类中自定义标题的位置(基于堆叠标题的代码松散地显示在此处输入链接描述).
作为最小测试,假设我只想在所有标题的位置添加固定偏移量:
layoutAttributesForElementsInRect
以便始终处理所有标题(这可能是问题的原因,我不确定)layoutAttributesForSupplementaryViewOfKind
完整的实施包含在本文末尾.
(顺便说一下,我知道在第一步中添加所有标题,包括那些在rect之外的标题,并不是严格说来,但这是一个简单的例子,说明我希望制作的位置更复杂,这会导致所有标题在绘制矩形中显示.)
但是,当我运行代码时,我得到以下内容NSInternalInconsistencyException
:
2014-01-15 00:41:50.130 CollectionStackedHeaders[60777:70b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'layout attributes for supplementary item at index path (<NSIndexPath: 0x8a7db90> {length = 2, path = 0 - 0})
changed from <UICollectionViewLayoutAttributes: 0x8a7f8b0> index path: (<NSIndexPath: 0x8a7d9c0> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 0; 320 50);
to <UICollectionViewLayoutAttributes: 0x8a7fb80> index path: (<NSIndexPath: 0x8a7db90> {length = 2, path = 0 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 50; 320 50); zIndex = 1024;
without invalidating the layout'
Run Code Online (Sandbox Code Playgroud)
这似乎是由更新属性引起的,就像我注释掉以下两行一样,它工作正常:
attributes.zIndex = 1024;
attributes.frame = frame;
Run Code Online (Sandbox Code Playgroud)
是什么导致了这个错误,我该怎么做才能让我的简单示例启动并运行?
以下是此简单示例的完整类实现:
@implementation myStackedHeaderFlowLayout
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
// Call super to get elements
NSMutableArray* answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
// As a test, always add first header to the answer array
NSArray* indexes = [NSArray arrayWithObjects: [NSNumber numberWithInt:0], nil];
for (NSNumber* sectionNumber in indexes) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:[sectionNumber integerValue]];
UICollectionViewLayoutAttributes* layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
if (layoutAttributes) {
[answer removeObject:layoutAttributes]; // remove if already present
[answer addObject:layoutAttributes];
}
}
return answer;
}
- (UICollectionViewLayoutAttributes*)layoutAttributesForSupplementaryViewOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath {
// Call super to get base attributes
UICollectionViewLayoutAttributes* attributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
CGRect frame = attributes.frame;
frame.origin.y += 50;
// Update attributes position here - causes the problem
attributes.zIndex = 1024;
attributes.frame = frame;
}
return attributes;
}
- (UICollectionViewLayoutAttributes*)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath {
UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
- (UICollectionViewLayoutAttributes*)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath {
UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
return YES;
}
@end
Run Code Online (Sandbox Code Playgroud)
tit*_*coy 16
layout attributes for supplementary item at index path (<NSIndexPath>)
changed from <UICollectionViewLayoutAttributes>
to <UICollectionViewLayoutAttributes>
without invalidating the layout
Run Code Online (Sandbox Code Playgroud)
根据我的经验,NSInternalInconsistencyException
当返回的数组layoutAttributesForElementsInRect:
包含UICollectionViewLayoutAttributes
具有相同索引路径和(补充)元素类别的两个对象时,抛出上面的描述.
好吧,我不是 100% 确定为什么,但layoutAttributesForElementsInRect
用以下内容替换似乎可以解决问题:
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
// Call super to get elements
NSMutableArray* answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
NSUInteger maxSectionIndex = 0;
for (NSUInteger idx=0; idx < [answer count]; ++idx) {
UICollectionViewLayoutAttributes *layoutAttributes = answer[idx];
if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell || layoutAttributes.representedElementCategory == UICollectionElementCategorySupplementaryView) {
// Keep track of the largest section index found in the rect (maxSectionIndex)
NSUInteger sectionIndex = (NSUInteger)layoutAttributes.indexPath.section;
if (sectionIndex > maxSectionIndex) {
maxSectionIndex = sectionIndex;
}
}
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
// Remove layout of header done by our super, as we will do it right later
[answer removeObjectAtIndex:idx];
idx--;
}
}
// Re-add all section headers for sections >= maxSectionIndex
for (NSUInteger idx=0; idx <= maxSectionIndex; ++idx) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
if (layoutAttributes) {
[answer addObject:layoutAttributes];
}
}
return answer;
}
Run Code Online (Sandbox Code Playgroud)
我只能想象 before 是在layoutAttributesForElementsInRect
我添加到第一部分的控件的标头正确初始化之前被调用的,因此以编程方式确定存在哪些标头可以避免这种情况?任何想法都是受欢迎的,但有了上述问题就解决了。
归档时间: |
|
查看次数: |
7602 次 |
最近记录: |