在方向更改时管理集合视图单元格布局的正确方法

时间:2016-07-05 06:50:30

标签: ios swift uicollectionview uicollectionviewcell uicollectionviewlayout

UICollectionView上的细胞很少,而且在旋转时,行数和列数会发生变化。我能够通过以下方式实现这一目标:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
    if UIDevice.currentDevice().orientation.isPortrait.boolValue{
        return CGSizeMake((collectionView.frame.size.width-2)/2, (collectionView.frame.size.height - 4)/3)
    }
    else{
        return CGSizeMake((collectionView.frame.size.width-4)/3, (collectionView.frame.size.height - 4)/3)
    }
}

一切都很好,直到设备旋转。为了轮换,我已经像这样重新加载了集合视图

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
    myCollectionView!.reloadData()
}

最终结果看起来像this。(抱歉GIF不好)

实现所需数量的细胞。但正如您从链接中可以看到的那样,短暂的一秒发生旋转时会发现间隙。这种效果是不希望的。另外,为了修复布局,不断重新加载UICollectionView是不好的。我能够实现我想要的但不能以正确的方式实现。一些专家的想法将不胜感激。

1 个答案:

答案 0 :(得分:0)

假设您有一个UICollectionViewFlowLayout:

,这是一个解决方案

首先,将其添加到ViewController:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ResultsCollectionViewController.orientationDidChange(_:)), name: UIDeviceOrientationDidChangeNotification, object: nil)

VC关闭时不要忘记删除self:

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

然后实现选择器方法:

func orientationDidChange(notification: NSNotification) {
    collectionView!.collectionViewLayout.invalidateLayout()
}

基本上,您只需在设备方向发生变化时发送通知,然后选择器会使您的布局无效,以便刷新。

编辑:

这是一个基本的UICollectionViewFlowLayout设置方法:

func setupCollectionViewLayout(minimumInteritemSpacing minimumInteritemSpacing: CGFloat, minimumLineSpacing: CGFloat) {
    let layout = UICollectionViewFlowLayout()
    layout.minimumInteritemSpacing = minimumInteritemSpacing
    layout.minimumLineSpacing = minimumLineSpacing
    collectionView?.collectionViewLayout = layout
}

然后在viewDidLoad中你可以调用:

// Setup a layout
setupCollectionViewLayout(minimumInteritemSpacing: 0, minimumLineSpacing: 0)

如果您希望使用UICollectionViewDelegateFlowLayout,可以使用以下模板,但请记住,您必须对其进行调整!

// ----------------------------------------------------------------------------------
// MARK: - UICollectionViewDelegateFlowLayout
// ----------------------------------------------------------------------------------

extension ResultsCollectionViewController: UICollectionViewDelegateFlowLayout {

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    switch UIDevice.currentDevice().userInterfaceIdiom {
    case .Phone:
        return CGSize(width: self.view.frame.width, height: 100.0)
    case .Pad:
        return CGSize(width: self.view.frame.width/2.0, height: 100.0)
    default:
        return CGSize(width: self.view.frame.width, height: 100.0)
    }


}

}