web-dev-qa-db-ja.com

セルがフルスクリーンのときにUICollectionViewがエラーを記録するのはなぜですか?

UICollectionViewControllerを使用するUICollectionViewFlowLayoutがあります。ここで、itemSizeUICollectionViewのサイズです。基本的に、これは各セルがフルスクリーンで水平にスクロールするセルの行レイアウトです。

UICollectionViewFlowLayoutサブクラスでは、prepareLayoutを次のようにオーバーライドしました。

- (void)prepareLayout {
    self.itemSize = self.collectionView.frame.size;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.collectionView.pagingEnabled = YES;
    self.minimumLineSpacing = 0.0;
    self.minimumInteritemSpacing = 0.0;
    self.sectionInset = UIEdgeInsetsZero;
    self.footerReferenceSize = CGSizeZero;
    self.headerReferenceSize = CGSizeZero;
}

UICollectionViewControllerは、1つのセクションで10個のアイテムを返す非常に基本的なものです。詳細については、 GitHubのサンプルプロジェクト を含めました。

すべてが正しくセットアップされているようです。シミュレーターとデバイスでは正しく表示されますが、コレクションビューが表示されると、コンソールにエラーが記録されます。

the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less that the height of the UICollectionView minus the section insets top and bottom values.

また、私の例のコレクションビューコントローラーはNavigation Controllerにあり、この例では特に必要ないように見えますが、実際のケースではコレクションビューコントローラーが必要ですナビゲーションコントローラー

31
Wes

UIViewController–_automaticallyAdjustsScrollViewInsets–には、デフォルトでYESに設定されているプロパティがあります。これは、UIViewControllerのビュー階層にUIScrollViewがある場合(UICollectionViewControllerに当てはまる場合)、そのスクロールビューのcontentInsetプロパティが調整されることを意味します。ステータスバー、ナビゲーションバー、ツールバー、またはタブバーによって消費される画面領域を自動的に考慮します。

そのプロパティのドキュメントには次のように記載されています。

AdjustsScrollViewInsets

View Controllerがスクロールビューのインセットを自動的に調整するかどうかを指定します。

@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets

ディスカッション

デフォルト値はYESです。これにより、ステータスバー、ナビゲーションバー、ツールバーまたはタブバーによって消費される画面領域に応じて、View Controllerがスクロールビューのインセットを調整できます。ビュー階層に複数のスクロールビューがある場合など、スクロールビューのインセット調整を自分で管理する場合は、NOに設定します。

解決策は、automaticallyAdjustsScrollViewInsetsのように、NOサブクラスのどこかにUICollectionViewControllerviewDidLoadに設定することです。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.automaticallyAdjustsScrollViewInsets = NO;
}

GitHubのサンプルプロジェクト を追加しました。これはこの問題と解決策を示しています。 2つのブランチがあります:with_errorおよびfixed_errorGitHubの変更の差分 です。

69
Wes

この問題は、3x画面(つまりiPhone 6 Plus)で発生しました。判明したように、自動レイアウトエンジンは無限浮動小数点値(.33333333など)を好まなかったため、私の解決策はfloorでした。 sizeForItemAt:indexPath:の戻り高さ。

return CGSize(width: preferredWidth, height: floor(preferredHeight))
4
Tamás Sengel

iOS 11アップデート:automaticallyAdjustsScrollViewInsetsはiOS 11.0で廃止されました。

アップルでは、​​代わりにUIScrollViewcontentInsetAdjustmentBehaviorメソッドを使用することをお勧めします。この値を.neverに設定すると、エラーがなくなりました。 Interface Builderでこのプロパティを設定することもできます。

3
Legonaftik

デバイスをポートレートからランドスケープに、ポートレートに戻すときにこの問題が発生しました。次のように、デバイスの回転時およびsuperの呼び出し前にcollectionViewのレイアウトを無効化します。

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    // Causes collection view cells to be resized upon orientation change.
    // Important that this is called *before* call to super in order to prevent error from being logged to console.
    [self.collectionView.collectionViewLayout invalidateLayout];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    //...
}
2
Stunner

iOS 10:一番上のビューがビューアウトレットに接続されていません

1
Anton Tropashko

同様の問題がありました。

スクリーンの全幅と高さのロードセルの後。いくつかの条件でセルの高さを変更すると、同じエラーが発生しました

これを修正する

私は使った

   func updateHeightPerRatio(with image:UIImage) {
    let ratio = collectionView.bounds.width / image.size.width
    constHeightCollectionView .constant =  ceil(image.size.height * ratio)
    collectionView.reloadData()
    collectionView.performBatchUpdates({
        collectionView.layoutIfNeeded()
    }) { (completed) in
        self.collectionView.reloadData()
        self.layoutIfNeeded()
    }
}

解決策は、データをリロードし、そのコレクションビューでバッチ更新を実行してフレームを再計算することです。コレクションビューを再度リロードした後、計算されたフレームをセルに適用します

そして今、問題のログはありません。

お役に立てば幸いです

0