在UICollectionView布局中自定义标头的位置会导致NSInternalInconsistencyException错误 [英] Customising position of header in UICollectionView layout causes NSInternalInconsistencyException error

查看:878
本文介绍了在UICollectionView布局中自定义标头的位置会导致NSInternalInconsistencyException错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用子类 UICollectionViewFlowLayout 类(基于松散地)自定义 UICollectionView 中标题的位置有关堆叠标题的代码,请参见在此处输入链接说明)。

I am trying to customise the positions of the headers in a UICollectionView using a subclassed UICollectionViewFlowLayout class (based loosely on the code for stacked headers which is shown enter link description here).

作为最小测试,假设我只想在所有标题的位置添加固定偏移量:

As a minimal test, let's say I just want to add a fixed offset to the position of all headers:


  • 我将所有标题添加到 layoutAttributesForElementsInRect 返回的数组中,以便始终处理所有标题(这可能是问题,我不确定)

  • 然后我通过在 layoutAttributesForSupplementaryViewOfKind
  • $中添加固定偏移量来更新每个标题b $ b
  • I add all headers to the array returned by layoutAttributesForElementsInRect so that all are always processed (this may be the cause of the problem, I'm not sure)
  • I then update each header by adding a fixed offset in layoutAttributesForSupplementaryViewOfKind

完整的实施包含在本文末尾。

The full implementation is included at the end of this post.

(顺便说一下,我知道添加所有标题,包括rect之外的标题,是在第一步中没有严格说来是必要的,但这是一个简单的例子,我希望制作一个更复杂的定制,这将导致所有标题显示在绘制矩形中。)

(By the way, I know that adding all headers, including those outside the rect, is not strictly speaking necessary in the first step, but this is a simplified example of a more complex customisation in position I want to make which would cause all headers to be displayed in the draw rect.)

然而,当我运行代码时,我得到以下 NSInternalInconsistencyException

However, when I run the code I get the following 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'

这似乎是由属性更新引起的,就像我注释掉以下两行一样,它可以正常工作:

It seems that this is caused by the update of the attributes, as if I comment out the following two lines it works fine:

attributes.zIndex = 1024;
attributes.frame = frame;

导致此错误的原因是什么,我该怎么做才能让我的简单示例启动并运行?

What is causing this error, and what can I do to get my simple example up and running?

以下是这个简单示例的完整类实现:

Here is the full class implementation for this simple example:

@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


推荐答案

layout attributes for supplementary item at index path (<NSIndexPath>) 
changed from <UICollectionViewLayoutAttributes> 
to <UICollectionViewLayoutAttributes>
without invalidating the layout

根据我的经验, NSInternalInconsistencyException <当从 layoutAttributesForElementsInRect:返回的数组包含两个 UICollectionViewLayoutAttributes 对象时,抛出上面描述的/ code> 相同的索引路径和(补充)元素类别。

In my experience, the NSInternalInconsistencyException with the description above is thrown when the array returned from layoutAttributesForElementsInRect: contains two UICollectionViewLayoutAttributes objects with the same index path and (supplementary) element category.

这篇关于在UICollectionView布局中自定义标头的位置会导致NSInternalInconsistencyException错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆