Swift:如何在设备旋转后刷新UICollectionView布局

我用UICollectionView(flowlayout)来构build一个简单的布局。 每个单元格的宽度设置为使用self.view.frame.width的屏幕宽度

但是当我旋转设备时,单元格不会被更新。

在这里输入图像说明

我发现了一个函数,这个函数被调用方向改变:

 override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { //code } 

但我无法find更新UICollectionView布局的方法

主要代码在这里:

 class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{ @IBOutlet weak var myCollection: UICollectionView! var numOfItemsInSecOne: Int! override func viewDidLoad() { super.viewDidLoad() numOfItemsInSecOne = 8 // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { //print("orientation Changed") } func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 1 } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return numOfItemsInSecOne } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellO", forIndexPath: indexPath) return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{ let itemSize = CGSize(width: self.view.frame.width, height: 100) return itemSize }} 

添加这个function:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() myCollection.collectionViewLayout.invalidateLayout() } 

当你改变方向时,这个函数会被调用。

更好的select是调用invalidateLayout()而不是reloadData()因为它不会强制单元格的重新创build,所以性能会稍微好一些:

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() myCollection.collectionViewLayout.invalidateLayout() } 

你也可以用这种方法使它失效。

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

您可以使用更新您的UICollectionView布局

 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { if isLandscape { return CGSizeMake(yourLandscapeWidth, yourLandscapeHeight) } else { return CGSizeMake(yourNonLandscapeWidth, yourNonLandscapeHeight) } } 

也可以使用更新UICollectionViewLayout traitCollectionDidChange方法:

 override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) guard let previousTraitCollection = previousTraitCollections else { return } collectionView?.collectionViewLayout.invalidateLayout() }