3

私は大規模なプロジェクトで AutoLayout を使い始めましたが、これにはかなり驚きました。ただし、回転とサイズのクラスに対応するようにプロジェクトを調整する必要があり、ビューを正しく動作させるのに大きな問題があります。

基本的な問題は、再び UICollectionViews を含むセルをUICollectionViews使用していることです。デバイスが回転すると、ベース コレクション ビューはそのセルを正しく調整しますが、ネストされたコレクション ビューのすべてのセルは新しいサイズに自動的に調整されません。

調査の結果、次のようになります。

  • が呼び出されたときviewWillTransitionToSize、ベース コレクション ビューはまだ回転していません (予想どおり)。
  • そのviewDidLayoutSubviewsが呼び出された後、ベースコレクションビューのサイズが回転しました-しかし、残念ながらそのセルはまだ-回転前の幅のままです
  • セル内のcoordinator animateAlongsideTransition ... completion:{}ブロックでもviewWillTransitionToSize、新しい幅はまだありません。

上記は、新しい幅がまだわからないため、ネストされたコレクション ビューのセルにサイズを変更するように指示できる場所がないことを意味します。また、自動レイアウト システムはそれらを自動的に調整しません。

他の誰かが同じ問題を抱えているか、解決策を知っていますか?

4

7 に答える 7

5

TheEyeに感謝します。私はこれをコメントとして彼らの応答に追加したかったのですが、どうやら私は十分なカルマを (まだ) 持っていないので、これを補遺と考えてください。

私は同じ問題を抱えていましたが、選択したときに uicollectionview のセルが「展開された状態」になります。ユーザーがデバイスを回転させて を呼び出すと[self.collectionview reloadData]、展開されたセルはすべてその状態を失います。performBatchUpdatesオプションで、セルの状態を失うことなく、コレクション ビューを呼び出して強制的にレイアウトすることができます。

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[self.collectionView.collectionViewLayout invalidateLayout];

[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {

} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    //[self.collectionView reloadData];//this works but reloading the view collapses any expanded cells.       
    [self.collectionView performBatchUpdates:nil completion:nil];       
}];  
}
于 2015-03-10T14:59:03.733 に答える
1

TheKey の応答は正しいです。ただし、データをリロードする代わりに、単に呼び出すことができます

UICollectionView.collectionViewLayout:finalizeCollectionViewUpdates()

例:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        self.collectionView.collectionViewLayout.invalidateLayout()
        self.collectionView.collectionViewLayout.finalizeCollectionViewUpdates()
    }
于 2015-08-27T11:26:45.003 に答える
1

代替ソリューションを提供したかった。コーディネーターのアニメーションの完了で reloadData または performBatchUpdates を呼び出す際のわずかな遅延が気に入らなかった。どちらも AutoLayout の警告が発生しました。

viewWillTransitionToSize 内で、表示されているネストされたすべてのコレクション ビューで invalidateLayout を呼び出し、最後に外側/トップ レベルのコレクション ビューで invalidateLayout を呼び出します。

子コレクション ビューを持つコレクション ビュー セル:

class NestableCollectionViewCell: UICollectionViewCell {
  @IBOutlet weak var collectionView: NestableCollectionView?
}

UICollectionView を拡張して、ネストされたコレクション ビューを無効にします。

class NestableCollectionView: UICollectionView {

  func invalidateNestedCollectionViews(){
    let visibleCellIndexPaths = self.indexPathsForVisibleItems()
    for cellIndex in visibleCellIndexPaths {
      if let nestedCell = self.cellForItemAtIndexPath(cellIndex) as? NestableCollectionViewCell {
        // invalidate any child collection views
        nestedCell.collectionView?.invalidateNestedCollectionViews()
        // finally, invalidate the cell's own collection view
        nestedCell.collectionView?.collectionViewLayout.invalidateLayout()
      }
    }
  }
}

そして、willTransitionToSize を無効にします。

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
  super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

  self.collectionView.invalidateNestedCollectionViews()
  self.collectionView.collectionViewLayout.invalidateLayout()
}
于 2015-12-23T17:26:33.593 に答える