简体   繁体   English

UICollectionView horizantal滚动照片库与swift

[英]UICollectionView horizantal scrolling Photo Gallery with swift

I'm trying to make a Photo Gallery using UICollectionView with Swift. 我正在尝试使用Swift的UICollectionView制作照片库。 I want to display photos in full screen and swipe right to get to the next image. 我想以全屏显示照片并向右滑动以进入下一张图像。 I have a working code for the portrait frame but as soon as I go to landscape it seems like my cell doesn't re-adjust itself to the correct position and size. 我有一个纵向框架的工作代码,但是一旦我去景观,我的单元格似乎没有重新调整到正确的位置和大小。

Meaning that it keeps the same width , height , x position and y position of the portrait screen at all times. 这意味着它始终保持纵向屏幕的widthheightx positiony position相同。 I also get this error on both portrait and landscape frame: 我也在纵向和横向框架上都出现此错误:

->the behavior of the UICollectionViewFlowLayout is not defined because: - >未定义UICollectionViewFlowLayout的行为,因为:

->the item height must be less that the height of the UICollectionView minus the section insets top and bottom values. - >项目高度必须小于UICollectionView的高度减去该部分的顶部和底部值。

I have looked all over the web for an answer and have tried all possible solutions but it doesn't seem to be working for me. 我已经在网上寻找答案,并尝试了所有可能的解决方案,但它似乎并不适合我。 Let me know if anyone can help out with this. 让我知道是否有人可以帮助解决这个问题。 Much appreciated. 非常感激。

Here is my code : 这是我的代码:

import UIKit

class ImageDetailViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout,UINavigationControllerDelegate {


@IBOutlet weak var imgDetailCollectionView: UICollectionView!

var index: Int!
var imageItems: Array<Items> = []
var currentIndex: CGFloat!
var size = UIScreen.mainScreen().bounds.size
init(index: Int , imageItems: Array<Items>) {
    self.index = index
    self.imageItems = imageItems
    super.init(nibName: "ImageDetailViewController", bundle: NSBundle.mainBundle())
}

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
    super.viewDidLoad()


    imgDetailCollectionView.registerNib(UINib(nibName: "ImageDetailCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ImageDetailCollectionViewCell")
    //self.automaticallyAdjustsScrollViewInsets = false
    imgDetailCollectionView.setZoomScale(0.5, animated: true)

}




override func viewDidLayoutSubviews() {
    imgDetailCollectionView.scrollRectToVisible(CGRectMake(320 * CGFloat(index), 0, 320 , 240), animated: false)
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{

    return self.imageItems.count
}


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{






    var cell = imgDetailCollectionView.dequeueReusableCellWithReuseIdentifier("ImageDetailCollectionViewCell", forIndexPath: indexPath) as ImageDetailCollectionViewCell

    cell.setup(imageItems[indexPath.row].url!)

    if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation)){


        self.imgDetailCollectionView.collectionViewLayout.invalidateLayout()

        var frame = cell.frame
        frame.size = CGSizeMake(size.width, size.height)
        cell.frame = frame

    }else{
        self.imgDetailCollectionView.collectionViewLayout.invalidateLayout()

        var frame = cell.frame
        frame.size = CGSizeMake(size.height, size.width)
        cell.frame = frame
    }

    return cell

}


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

    var size = UIScreen.mainScreen().bounds.size

    if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation)){


        return CGSizeMake(size.width, size.height)


    }else{

        return CGSizeMake(size.height, size.width)
    }



}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}


override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    self.imgDetailCollectionView.collectionViewLayout.invalidateLayout()

    var currentOffset = self.imgDetailCollectionView.contentOffset
    self.currentIndex = currentOffset.x / imgDetailCollectionView.frame.size.width

}


override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {

    var currentSize = imgDetailCollectionView.bounds.size
    var offset = self.currentIndex * currentSize.width
    imgDetailCollectionView.setContentOffset(CGPointMake(offset, 0), animated: false)

    imgDetailCollectionView.reloadData()
}

override func willAnimateRotationToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {

    self.imgDetailCollectionView.collectionViewLayout.invalidateLayout()
}
}

Your problem is you are checking the orientation and using the height for the width when it is in landscape mode. 您的问题是在横向模式下检查方向并使用高度作为宽度。 This is incorrect. 这是不正确的。 When the device is rotated, the width property will return the actual height of the device when it was in portrait. 旋转设备时,width属性将返回设备处于纵向时的实际高度。

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell = imgDetailCollectionView.dequeueReusableCellWithReuseIdentifier("ImageDetailCollectionViewCell", forIndexPath: indexPath) as ImageDetailCollectionViewCell
    cell.setup(imageItems[indexPath.row].url!)
    cell.frame.size = view.frame.size
    return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSizeMake(view.frame.width, view.frame.height)
}

Also another note, apple recommends that you use the viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) method because this is the newer API. 另外需要注意的是,apple建议您使用viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)方法,因为这是较新的API。 Also, in iOS9 if you use this method instead you will be enabling the multitasking feature by using this method. 此外,在iOS9中,如果您使用此方法,则将使用此方法启用多任务处理功能。

This error might be printed because of next line: 由于下一行,可能会打印此错误:

var size = UIScreen.mainScreen().bounds.size var size = UIScreen.mainScreen()。bounds.size

For fast check you can type for example: 为了快速检查,您可以输入例如:

var size = UIScreen.mainScreen().bounds.size * 0.25 var size = UIScreen.mainScreen()。bounds.size * 0.25

If error message dissapear, you should follow instructions from message and subtract collectionView's contentInsets and sectionInsets from available height (collectionView.bounds.height). 如果错误消息消失,您应该按照消息中的说明从可用高度(collectionView.bounds.height)中减去collectionView的contentInsets和sectionInsets。

Doing so, you will avoid situation in which cell height is trying to be 'higher' than it's collectionView. 这样做,您将避免单元格高度试图比它的collectionView“更高”的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM