快速旋转 UIColectionView 时的水平滚动

Posted

技术标签:

【中文标题】快速旋转 UIColectionView 时的水平滚动【英文标题】:Horizontal scroll when rotate UIColectionView in swift 【发布时间】:2014-07-28 13:01:23 【问题描述】:

我正在尝试快速构建collectionView,我希望当设备处于纵向时collectionView 垂直滚动,而当我在横向模式下旋转设备时collectionView 水平滚动。这是CollectionView 类:

class SceneBuilderVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource
    @IBOutlet var collection: UICollectionView!

    override func viewDidLoad() 
       super.viewDidLoad()
    

    override func shouldAutorotate() -> Bool
       return true
    

    override func supportedInterfaceOrientations() -> Int
        return Int(UIInterfaceOrientationMask.All.toRaw())
    

    func numberOfSectionsInCollectionView(collectionView: UICollectionView!) -> Int 
        return 1;
    

    func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int 
           return 50;
    

    func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
        var cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as UICollectionViewCell
        cell.backgroundColor = UIColor.redColor()
        return cell
    

要更改滚动方向,我需要更改 collectionView 布局。

var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
var scrollDirection = UICollectionViewScrollDirection.Vertical
flowLayout.scrollDirection = scrollDirection
self.collection.collectionViewLayout = flowLayout

另外,在 ios8 中,Apple 将屏幕旋转方式 willRotateToInterfaceOrientation:duration 改为 viewWillTransitionToSize:withTransitionCoordinator

如何使用 **viewWillTransitionToSize:withTransitionCoordinator* 方法检查设备何时旋转并因此更改滚动方向?

【问题讨论】:

【参考方案1】:

使用 animateAlongsideTransition 中的完成处理程序检查旋转后的方向并进行任何调整。

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) 
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    coordinator.animateAlongsideTransition(nil, completion: context in
        if(UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait || UIDevice.currentDevice().orientation == UIDeviceOrientation.PortraitUpsideDown)
            //this is portrait (or upsidedown), do something
        else
            //landscape 
        
    )

但除非在特殊情况下,您不应该真正关心设备的确切方向,您可以简单地将视图调整为“新尺寸”

【讨论】:

【参考方案2】:

选项 #1:

如果您的集合视图占据了整个屏幕,那么您可以简单地检查宽度是否大于高度并将结果作为横向。

选项 #2:

或者你可以使用函数:

UIInterfaceOrientationIsLandscape(self.interfaceOrientation) 

但你应该知道 interfaceOrientation 属性在 iOS8 中已被弃用。

【讨论】:

如果我使用选项 1,我必须在哪里检查它?因为没有一个函数会在每次设备改变方向时被调用。 检查viewWillTransitionToSize:withTransitionCoordinator: 中的size 属性。 viewWillTransitionToSize:withTransitionCoordinator: 每次设备旋转时都会被调用。但它不会在初始加载视图时被调用,因此您应该在viewDidLoad(或任何其他合适的方法)中手动调用。【参考方案3】:

这就是完整的功能:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator   coordinator: UIViewControllerTransitionCoordinator!)
    if let theAppDelegate = UIApplication.sharedApplication() 
        let orientation = theAppDelegate.statusBarOrientation
        if orientation.isPortrait 
            println("Landscape")
            var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            //flowLayout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
            //flowLayout.itemSize = CGSizeMake(80, 80)
            var scrollDirection = UICollectionViewScrollDirection.Horizontal
            flowLayout.scrollDirection = scrollDirection
            self.collection.collectionViewLayout = flowLayout
        else
            println("Protrait")
            var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            // flowLayout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
            //flowLayout.itemSize = CGSizeMake(80, 80)
            var scrollDirection = UICollectionViewScrollDirection.Vertical
            flowLayout.scrollDirection = scrollDirection
            self.collection.collectionViewLayout = flowLayout
        
    

【讨论】:

不起作用:状态栏的方向是在方向更改发生之前...并且您不知道更改是 90 度还是 180 度或其他。所以这行不通。根据shinobicontrols.com/blog/posts/2014/08/06/…,我认为您必须查看协调器上的 targetTransform()。

以上是关于快速旋转 UIColectionView 时的水平滚动的主要内容,如果未能解决你的问题,请参考以下文章

UIColectionView Vertical Scrolling inside a Scrollview - 在集合视图区域中滚动时禁用滚动视图的滚动

旋转到横向时的Exoplayer方向问题

如何使用 CSS 水平旋转图像

Canny 边缘检测未检测到 100% 水平/未旋转的线

触摸滚动视图时的 UIImageView 旋转 - iOS

悬停时的旋转按钮