Отрицательные или нулевые размеры не поддерживаются в макете потока
У меня довольно сложная ячейка collectionView, и я заметил, что если я очень быстро прокручиваю свой файл collectionView, это приведет к сбою приложения.
Одна из ошибок, которые я получил, это:
negative or zero sizes are not supported in the flow layout
Я заметил, что я просто возвращаю значение float, например. 500, в моем методе UICollectionView sizeForItemAtIndexPath:
он не сбой.
В моем представлении коллекции есть динамические высоты ячеек.
Я разбираю строку HTML Attributed в моем методе sizeForItemAtIndexPath:
, используя эту библиотеку:
https://github.com/mmislam101/HTMLAttributedString
Кто-нибудь знает, что вызывает, в частности, указанное сообщение об ошибке?
Update
Другая ошибка, которую я также вижу в моем отчете Bugsense, связанном с этим сбоем:
- [__ NSArrayM objectAtIndex:]: индекс 2 за пределами границ [0.. 1]
Это происходит, когда я прокручиваю слишком быстро =/
Обновление 2
Bugsense stacktrace показывает, что вызовы метода аварийного вызова:
1) collectionView: layout: sizeForItemAtIndexPath:
2) calculateFeedCellHeightForIndexPath: (это один из моих собственных методов, а не Apple)
3) dynamicHeightForHTMLAttributedString: UsingWidth: AndFont: (это один из моих собственных методов, а не Apple)
4) HTMLAttributedString attribittedStringWithHtml: andBodyFont: строка 35
5) HTMLAttributedString attribittedString строка 79
6) scrollViewDidScroll: строка 174
7) setFeedFooterHeight: анимированный: строка 124
Мой setFeedFooterHeight: анимированный: метод:
-(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 reload, пока uicollection.isTracking не станет ложным?
Я пробовал это, но, похоже, не помог.
Обновление 3
ОК, я случайно наткнулся на причину этой ошибки.
Это связано с вызовом [collectionView.collectionFlowLayout invalidateLayout];
.
Я добавил задержку в 1,0 секунды, и проблема, похоже, исчезла.
Ответы
Ответ 1
Я думаю, что это ошибка iOS 8, связанная с методами делегирования /datasource UICollectionView и/или NSAttributedString.
Я могу получить этот же крах в одном проекте, создав 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];
в, скажем:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
Это, кажется, заставляет что-то (возможно, парсер?) инициализировать, так что, когда я тогда использую аналогичный код в:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
он не падает. Сумасшедший город.
Я собираюсь загрузить 8.1 beta 2 и протестировать там и отчитаться.
Ответ 2
Я начал получать эту ошибку (многие из них), когда я добавил следующий ключ в свой info.plist
View controller-based status bar appearance
и установите для него значение НЕТ.
Если я верну его обратно на "да", ошибка исчезнет. Связанный? Возможно.