流布局中不支持负值或零大小

时间:2014-10-08 04:59:47

标签: ios uicollectionview autolayout uicollectionviewcell

我有一个相当复杂的collectionView单元格,我注意到如果我在我的collectionView上滚动得非常快,它会崩溃应用程序。

我得到的一个错误是:

negative or zero sizes are not supported in the flow layout

我注意到我只是返回一个浮点值,例如500,在我的UICollectionView sizeForItemAtIndexPath:方法中,它不会崩溃。

我的集合视图具有动态单元格高度。

我正在使用此库在我的sizeForItemAtIndexPath:方法中解析HTML Attributed字符串:

https://github.com/mmislam101/HTMLAttributedString

有人知道导致上述错误消息的原因是什么吗?

更新

我在Bugsense报告中看到的与此次崩溃有关的另一个错误是:

- [__ NSArrayM objectAtIndex:]:索引2超出界限[0 .. 1]

当我滚动太快= /

时会发生这种情况

更新2

Bugsense stacktrace显示崩溃顺序方法调用是:

1)collectionView:layout:sizeForItemAtIndexPath:

2)calculateFeedCellHeightForIndexPath :(这是我自己的方法之一,而不是Apple的方法)

3)dynamicHeightForHTMLAttributedString:UsingWidth:AndFont :(这是我自己的方法之一,而不是Apple的方法)

4)HTMLAttributedString attributionStringWithHtml:andBodyFont:第35行

5)HTMLAttributedString attributionString第79行

6)scrollViewDidScroll:第174行

7)setFeedFooterHeight:animated:line 124

我的setFeedFooterHeight:animated:方法是:

-(void)setFeedFooterHeight:(CGFloat)newHeight animated:(BOOL)animated
{
    footerHeightConstraint.constant = newHeight;

    if(animated)
    {
        [UIView animateWithDuration:0.35 animations:^{
            [self layoutIfNeeded];  // <------ crash on this line it seems
        }];
    }
    else
    {
        [self.feedFooterView layoutIfNeeded];
    }
}

然而,当我直接从Xcode运行应用程序而不是如上所述的Testflight时,Xcode在上面的步骤5停止,这产生了这段代码:

- (NSAttributedString *)attributedString
{
    __block NSString *css       = @"<style>";

    [_cssAttributes enumerateObjectsUsingBlock:^(NSString *cssAttribute, NSUInteger idx, BOOL *stop) {
        css = [css stringByAppendingString:cssAttribute];
    }];

    css                         = [css stringByAppendingString:@"</style>"];
    NSString *htmlBody          = [_html stringByAppendingString:css];

    NSStringEncoding encoding   = NSUnicodeStringEncoding;
    NSData *data                = [htmlBody dataUsingEncoding:encoding];

    NSDictionary *options       = @{NSDocumentTypeDocumentAttribute         : NSHTMLTextDocumentType,
                                    NSCharacterEncodingDocumentAttribute    : @(encoding)};

    // app crashes here on this next line.
    NSAttributedString *body    = [[NSAttributedString alloc] initWithData:data
                                                                options:options
                                                     documentAttributes:nil
                                                                  error:nil];

    return body;
}

我在其他主题上读到了关于包装uicollectionview重新加载的内容,直到uicollection.isTracking变为false?

我试过了,但似乎没有帮助。

更新3

好的,我偶然发现了这个错误的原因。

这与[collectionView.collectionFlowLayout invalidateLayout];电话有关。

我添加了1.0秒的延迟,问题似乎消失了。

5 个答案:

答案 0 :(得分:4)

我认为这是与UICollectionView的委托/数据源方法和/或NSAttributedString相关的iOS 8错误。

我可以通过NSAttributedString中的HTML创建sizeForItemAtIndexPath:,在一个项目中遇到同样的崩溃如果我在numberOfRows:创建了一个属性字符串 崩溃:很可能是UIKit中的问题未正确初始化,或者HTML解析器与UICollectionView大小调整方法之一共享缓冲区。

iOS 7.1上的

注意:我得到了一个不同的异常:“UICollectionView收到了一个不存在索引路径的单元格的布局属性:”


尝试此实验:请拨打以下内容:

NSData *data = [@"<a href=\"http://www.google.com\">link</a>" dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString *s = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}  documentAttributes:nil error:nil];

in,say:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

这似乎强制某些东西(可能是一个解析器?)被初始化,这样当我然后使用类似的代码时:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

它没有崩溃。疯狂的小镇。

我将下载8.1 beta 2并在那里进行测试,并将报告回来。

答案 1 :(得分:1)

确保在代码中定义collectionViewLayout.itemSize的地方大小不包含负/零值

答案 2 :(得分:0)

由于某些错误的计算逻辑,我发送的宽度为sizeForItemAt -6时我的应用程序崩溃了

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: width, height: height)
}

宽度高度应始终为非负数(> = 0)

答案 3 :(得分:0)

使用此

func collectionView(_ collectionView:UICollectionView,布局collectionViewLayout:UICollectionViewLayout,sizeForItemAt indexPath:IndexPath)-> CGSize {

    if width <= 0 || height <= 0{
        return CGSize(width: 0, height: 0)
    }

}

答案 4 :(得分:-2)

当我将以下密钥添加到我的info.plist中时,我开始收到此错误(很多错误)

View controller-based status bar appearance

并将其值设置为NO。

如果我将其切换回是,则错误消失。有关?有可能。