web-dev-qa-db-ja.com

iOS 8でUICollectionViewCellsの自動レイアウトサイズを取得するにはどうすればよいですか? (systemLayoutSizeFittingSizeは、iOS 8では高さがゼロのサイズを返します)

IOS 8以降、[UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]は高さ0のサイズを返します。

コードは次のとおりです:

IOS 7のUICollectionViewのセルのサイズを決定するには、自動レイアウトを使用してxibファイルで定義されたセルでsystemLayoutSizeFittingSize:を使用します。サイズは、私のxibファイルのUILabelのサブビューであるUICollectionViewCellのフォントサイズに依存します。ラベルのフォントは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では機能しません。残念ながら、その理由はわかりません。

iOS 8でUICollectionViewCellsの自動レイアウトサイズを取得するにはどうすればよいですか?

PS:使用

 return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

の代わりに

 return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

誰かが示唆するように、違いはありません。

24
martn_st

これは正式にバグのようです:私は this one の複製としてクローズされたレポートを提出しました

Beta 6がリリースされたときに報告します。

[Update:GMシードで正常に動作し、バグはAppleによってクローズされました。]

7

あなたがしなければならないことは、すべてのコンテンツをコンテナビューでラップし、次に呼び出すことです:

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

セルは次のようになります。セル-> containerView->サブビュー

これはios7とios8の両方で機能します。

おそらくios8では、推定サイズを設定するだけでセルは自動的に自動サイズ調整されます。どうやらそれはベータ6の時点では機能していません。

8
Triet Luong

現在、回避策を使用しています。以下にコピーします。うまくいけば、これらの問題はiOS 8のリリース前に解決される予定であり、これを削除することができます。 (kludgeはAppleの暗黙的なcontentView動作の知識を前提としているため、転送する制約に対してIBアウトレットの参照をハックする必要があります。)

また、アップグレード中にすべてのautoresizingMaskがストーリーボード/ NIBから削除されていることに気づきました。これは、自動レイアウトであるはずですが、コレクションビューはまだスプリングとストラットに戻っています。おそらくこれはパージで見落とされているのでしょうか?

-ダン

/**
 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];
}
4
PlayfulGeek

これは、iOS7デバイスで実行されているxCode6およびiOS 8 SDKのバグです。最後に、UICollectionViewCellサブクラスで以下のコードを処理しました。これが次のバージョンで修正されることを願っています

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

UITableViewCellsとiOS 7でも同じ問題がありましたが(ios8は完全に動作します)、「Triet Luong」ソリューションがうまくいきました。

return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
0
Davis

これはバグではありません。私はしばらくの間この問題に取り組んでいて、さまざまなことを試しました。私のために働いている手順を以下に示します:

1)contentView [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]を使用します。

2)独自のcontentViewを作成し、subViewをcontentViewに追加できます。カスタムcontentViewを使用している場合は、contentViewの上下左右を固定することを忘れないでください。これを行うと、高さが0になります。これも、要件に応じて異なります。たとえば、contentViewの下部をsuperViewに固定しないでビューの高さを変えることができますが、固定は重要であり、どれが要件に依存するかを固定します。

3)要件に応じてインターフェイスビルダーで制約を適切に設定します。インターフェイスビルダーでは追加できない制約がありますが、viewControllerのviewDidLoadで追加できます。

したがって、私の2セントの入力は、正しいサイズを返すためにsystemLayoutSizeFittingSize:UILayoutFittingCompressedSizeのインターフェイスビルダーで制約を適切に設定する必要があるということです。これは解決策です。

0
Sam Paul

多分あなたはいくつかの間違った制約があるかもしれませんIViewとcontentViewの間に仮想の上部スペースと下部のスペースの両方を指定する必要があります、私は以前にもこの問題を抱えていました、それは私が仮想の上部スペースを指定しただけでしたので、実質的な下部スペースをcontentViewに指定していません

0
Gene