Как получить размер автоматической компоновки UICollectionViewCells в iOS 8? (systemLayoutSizeFittingSize возвращает размер с нулевой высотой в iOS 8)

начиная с iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] возвращает размер с высотой 0.

вот, что делает этот код:

чтобы определить размер ячейки в UICollectionView в iOS 7 я использую systemLayoutSizeFittingSize: в ячейке, определенной в xib-файле с помощью auto layout. Размер зависит от размера шрифта UILabel будучи подвидом UICollectionViewCell в моем xib-файле. Шрифт метки установлен в UIFontTextStyleBody. Таким образом, в основном размер ячейки зависит от настройки размера шрифта, сделанной в iOS 7.

вот сам код:

+ (CGSize)cellSize {
    UINib *nib = [UINib nibWithNibName:NSStringFromClass([MyCollectionViewCell class]) bundle:nil];

    // Assumption: The XIB file only contains a single root UIView.
    UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];

    if ([rootView isKindOfClass:[MyCollectionViewCell class]]) {
        MyCollectionViewCell *sampleCell = (MyCollectionViewCell*)rootView;
        sampleCell.label.text = @"foo"; // sample text without bar

        [sampleCell setNeedsLayout];
        [sampleCell layoutIfNeeded];

        return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    }

    return CGSizeZero;

}

он отлично работает в iOS 7, но не в iOS 8. К сожалению, я понятия не имею, почему.

как я могу получить автоматический размер макета UICollectionViewCells в iOS 8?

PS: используя

 return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

вместо

 return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

как кто-то может предложить, не имеет никакого значения.

8 ответов


похоже, это официально ошибка: Я подал отчет, который был закрыт как дубликат этот

сообщит, когда бета-6 выйдет.

[обновление: работает должным образом в семени GM iOS 8, и ошибка была закрыта Apple.]


что вам нужно сделать, это обернуть все содержимое в контейнер, то звоните:

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

ваша ячейка должна выглядеть так: ячейка -> containerView -> sub views

это работает как на ios7 , так и на ios8.

предположительно на ios8, все, что вам нужно сделать, это установить estimateSize & cell автоматически автоматический размер самостоятельно. По-видимому, это не работает с бета-6.


сейчас мы используем обходной путь, скопированный ниже. Надеюсь, эти проблемы будут решены до выпуска iOS 8, и мы можем удалить это. (Kludge предполагает знание неявного поведения contentView Apple, и мы должны взломать ссылки IB outlet на любые ограничения, которые мы передаем.)

мы замечаем, что они также удаляют все маски автозапуска из раскадровок/наконечников во время обновления, что имеет смысл, учитывая, что он должен быть автоматическим макетом, но представления коллекции по-прежнему весны & распорки. Возможно, это было упущено во время чистки?

--Dan

/**
 Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8.  Call this on the collection view cell before it is used, such as in awakeFromNib.  Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.

 Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell.  In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed.  However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview).  This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize.  Transferring those constraints to be on the contentView seems to fix the issue.

 Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height.  When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins.  Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it's content view.  Restore the previous behavior.

 Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn't available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {

    // transfer constraints involving descendants on cell to contentView
    UIView *contentView = cell.contentView;
    NSArray *cellConstraints = [cell constraints];
    for (NSLayoutConstraint *cellConstraint in cellConstraints) {
        if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
            NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
            parallelConstraint.priority = cellConstraint.priority;
            [cell removeConstraint:cellConstraint];
            [contentView addConstraint:parallelConstraint];
        } else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
            NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
            parallelConstraint.priority = cellConstraint.priority;
            [cell removeConstraint:cellConstraint];
            [contentView addConstraint:parallelConstraint];
        }
    }

    // restore auto-resizing mask to iOS 7 behavior
    contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];
}

это ошибка в XCODE6 и iOS 8 SDK, работающих на устройствах iOS7 :) Это почти остановило мой день. Наконец, он работал с приведенным ниже кодом в подклассе uicollectionviewcell. Я надеюсь, что это будет исправлено со следующей версией

- (void)setBounds:(CGRect)bounds {
    [super setBounds:bounds];
    self.contentView.frame = bounds;
}

У меня была такая же проблема для UITableViewCells и iOS 7 (ios8 работает отлично), но решение "Triet Luong" работало для меня:

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

Это не ошибка, я боролся с этой проблемой в течение некоторого времени и пробовал разные вещи, я даю ниже шаги, которые работали для меня:

1) Используйте contentView [sampleCell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];

2) Вы можете создать свой собственный contentView и добавить подвиды в contentView, не забудьте закрепить верхнюю, нижнюю и левую и правую части contentView, если вы используете пользовательский contentView для супервизора, если вы этого не сделаете, высота будет равна 0, здесь также в зависимости от ваших требований. e.g не прикреплять нижнюю часть contentView к супервизору, чтобы высота представления могла изменяться, но закрепление важно и закрепление, которое зависит от ваших требований.

3) установите ограничения правильно в interface builder в зависимости от ваших требований, есть определенные ограничения, которые не могут быть добавлены в interface builder, но затем вы можно добавить их в viewDidLoad viewController.

таким образом, мои 2 цента ввода в том, что ограничения должны быть установлены правильно в построителе интерфейса для systemLayoutSizeFittingSize:UILayoutFittingCompressedSize для возврата правильных размеров, это решение ребята.


может быть, у вас есть какие-то неправильные ограничения,вы должны указать как виртуальное верхнее пространство, так и нижнее пространство между вашим UIView и contentView, Я также имел эту проблему раньше, потому что я только что указали virtical верхней части пространства, и не указанные в virtical нижнее пространство на странице просмотр содержимого


Это была ошибка в бета-версии iOS 8. наконец, он исправлен для iOS 8 GB (Build 12A365). поэтому для меня теперь он работает с тем же кодом, который я написал для iOS 7. (см. вопрос)