it-roy-ru.com

отрицательные или нулевые размеры не поддерживаются в макете потока

Я получил довольно сложную ячейку collectionView и заметил, что, если я прокручиваю очень быстро на collectionView, происходит сбой приложения.

Одна из ошибок, которые я получил, заключается в следующем:

negative or zero sizes are not supported in the flow layout

Я заметил, что если я просто верну значение с плавающей точкой, например 500, в моем методе UICollectionView sizeForItemAtIndexPath: он не падает.

Мой вид коллекции имеет динамическую высоту ячеек.

Я анализирую строку HTML Attributed в моем методе sizeForItemAtIndexPath:, используя эту библиотеку:

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) HTMLAttributedStringributedStringWithHtml: andBodyFont: строка 35

5) HTMLAttributedString attribuString строка 79

6) scrollViewDidScroll: строка 174

7) setFeedFooterHeight: animated: строка 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 не станет ложным?

Я попробовал это, но, похоже, не помогло.

Обновление 3

Хорошо, я случайно наткнулся на причину этой ошибки.

Это связано с вызовом [collectionView.collectionFlowLayout invalidateLayout];.

Я добавил задержку 1,0 секунды, и проблема, похоже, исчезла.

14
Zhang

Я думаю, что это ошибка iOS 8, связанная с методами делегата/источника данных UICollectionView и/или NSAttributedString.

Я могу получить тот же сбой в одном проекте, создав NSAttributedString из HTML в sizeForItemAtIndexPath:. Если я создаю атрибутивную строку first в 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];

в, скажем: 

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

Кажется, это заставляет что-то инициализировать (возможно, парсер?), Когда я затем использую подобный код в: 

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

это не терпит крах. Сумасшедший город.

Я собираюсь скачать 8.1 бета 2 и протестировать там, и сообщу обратно.

4
Philip McDermott

убедитесь, что в вашем коде, где вы определяете collectionViewLayout.itemSize, размер не содержит отрицательных/нулевых значений

1
Aleksey Mazurenko

Использовать этот 

func collectionView (_ collectionView: UICollectionView, макет collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

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

}

0
CrazyPro007

В моем приложении произошел сбой, так как я отправлял ширину -6 для sizeForItemAt из-за неправильной логики вычислений

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

ширина & высота всегда должно быть неотрицательные числа (> = 0)

0
keshav