2016-04-27 83 views
16

我使用UICollectionView(flowlayout)来构建简单的布局。 每个单元格的宽度设置为使用的屏幕宽度self.view.frame.widthSwift:如何在设备旋转后刷新UICollectionView布局

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

enter image description here

我找到了一个功能,它是在方向变化称为:

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

,但我无法找到一个方法来更新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 
    }} 

回答

13

添加此函数:

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

当您更改方向时,将调用此函数。

+0

感谢@ khuong291如果我没有我的CollectionView的对象,我有UICollectionViewController?我将如何调用reloadData? –

+2

UICollectionViewController已经具有'collectionView'属性,所以你只要按照我所说的调用它们。只需将它们编辑为'collectionView.reloadData()'。它会工作。 – Khuong

+2

所以你需要重新加载视图,你不能只是触发布局刷新? – Rivera

1

您可以通过使用

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

更好的选择更新UICollectionView布局是调用invalidateLayout()而不是reloadData()因为它不会迫使细胞的娱乐,所以性能会稍好一些:

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

这是正确的方法。这应该是被接受的答案。 – thesummersign

+0

这是正确的方法来做到这一点..不是再次加载数据 –

+3

,导致我暗恋。当我在viewDidLayoutSubviews函数中放置一个打印语句时,识别出一个无限循环。 – nyxee

3

你也可以通过这种方式使它无效。

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { 
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 

    [self.collectionView.collectionViewLayout invalidateLayout]; 
} 
0

更新UICollectionViewLayouttraitCollectionDidChange方法可能被使用:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
    super.traitCollectionDidChange(previousTraitCollection) 

    guard let previousTraitCollection = previousTraitCollections else { 
     return 
    } 
    collectionView?.collectionViewLayout.invalidateLayout() 
} 
0

的viewWillLayoutSubviews()对我没有工作。 viewDidLayoutSubviews()也没有。两者都使应用程序进入无限循环,我使用打印命令进行了检查。

一个是做工作的方法之一是

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
// Reload here 
} 
相关问题