Подтвердить что ты не робот

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

Так как iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] возвращает размер с высотой 0.

Вот что делает код:

Чтобы определить размер ячейки в UICollectionView в iOS 7, я использую systemLayoutSizeFittingSize: в ячейке, определенной в файле xib, используя автоматическую компоновку. Размер зависит от размера шрифта 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];

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

4b9b3361

Ответ 1

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

Откроется отчет после выхода бета-версии 6.

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

Ответ 2

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

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

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

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

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

Ответ 3

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

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

- 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 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];
}

Ответ 4

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

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

Ответ 5

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

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

Ответ 6

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

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

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

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

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

Ответ 7

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

Ответ 8

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