无法使用自己的IndexPath加载UICollectionView,在将单元格中的项目打印到以下位置时,也会随机添加IndexPath:

时间:2019-01-20 06:05:27

标签: ios swift xcode uicollectionview uicollectionviewcell

我正在尝试创建一个Gallery应用,非常类似于iOS设备中已内置的应用。我添加了一些随机图像作为源数据,并设置了两个视图控制器,两个都是“集合”视图,但第一个显示所有可用图像,第二个分别显示每个图像。当我导航到第二个视图控制器(您可以在其中看到单个图像)时,问题就开始出现;当我尝试水平滚动时,总是出现同一张照片,它永远不会改变或遍历imagesArray(它为UICollectionView Data提供了源)资源)。即使UIImageArray中有四个图像,当我导航到第二个视图控制器时,我也可以前后滚动,但始终会出现同一张照片。我希望它的行为使用户可以前后滚动并查看数组中的每个图像(iOS Gallery App中也是一样)

该应用程序应该加载用户选择的图像,但是可以加载,但是当我滚动时它会保留在同一图像中。该应用程序确切地知道在第一个视图控制器中使用indexPath中给出的indexPath在imagesArray中检索什么图像,并在prepareForSegue方法中将其推送到第二个图像中,当我这样做时,将显示用户选择的图像,但仅显示该图像。该引用存储在一个名为“ passedContentOffSet”的变量中,该变量引用先前ViewController的indexPath。然后,我使用passedContentOffSet.item来填充第二个视图控制器的集合视图的数据,但是它发生了上述问题。我将其更改为indexPath.item,现在集合视图可以滚动浏览所有可用的图像,但是它始终从第一张图像开始,而不是从用户选择的图像开始。

First View Controller(垂直显示所有图像)

class CollectionViewController: UIViewController, UINavigationBarDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout  {
    let context =   (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    @IBOutlet weak var collectionView: UICollectionView!
    struct Storyboard {
        static let photoCell = "PhotoCell"
        static let sectionHeaderView = "SectionHeaderView"
        static let showDetailVC = "ShowImageDetail"

        static let leftAndRightPaddings: CGFloat = 2.0
        static let numberOfItemsPerRow: CGFloat = 3.0


    }

    var images:[UIImage] = [UIImage(named: "facebook")!, UIImage(named: "pinterest")!, UIImage(named: "linkedin")!, UIImage(named: "amazon")! ]

    @IBOutlet weak var toolBar: UIToolbar!

    var selectedIndexPath:IndexPath = IndexPath()

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.backBarButtonItem?.tintColor = UIColor.white

        collectionView.delegate = self
        collectionView.reloadData()
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let collectionViewWidth = collectionView.frame.width
        let itemWidth = (collectionViewWidth - Storyboard.leftAndRightPaddings) / Storyboard.numberOfItemsPerRow
        return CGSize(width: itemWidth, height: itemWidth)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return images.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photo", for: indexPath) as! CollectionViewCell

        let selectedItem = images[indexPath.row]

        cell.userImageView.image = selectedItem

        return cell
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedIndexPath = indexPath
        performSegue(withIdentifier: "goToDescription", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToDescription" {

            let destinationVC = segue.destination as! ImagePreviewVC
            destinationVC.images = images
            destinationVC.passedContentOffset = selectedIndexPath

        }
    }
}

现在,第二个View Controller,该应用程序应该在其中向用户显示用户选择的单个图像,并且还能够水平滚动以查看其他图像

class ImagePreviewVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout  {
    var myCollectionView: UICollectionView!
    var imgArray = [UIImage]()
    var passedContentOffset = IndexPath()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        self.view.backgroundColor=UIColor.black

        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        layout.minimumInteritemSpacing=0
        layout.minimumLineSpacing=0
        layout.scrollDirection = .horizontal

        myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        myCollectionView.delegate=self
        myCollectionView.dataSource=self
        myCollectionView.register(ImagePreviewFullViewCell.self, forCellWithReuseIdentifier: "Cell")
        myCollectionView.isPagingEnabled = true
        myCollectionView.scrollToItem(at: passedContentOffset, at: .left, animated: true)

        self.view.addSubview(myCollectionView)

        myCollectionView.autoresizingMask = UIViewAutoresizing(rawValue: UIViewAutoresizing.RawValue(UInt8(UIViewAutoresizing.flexibleWidth.rawValue) | UInt8(UIViewAutoresizing.flexibleHeight.rawValue)))
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imgArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell=collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImagePreviewFullViewCell
        cell.imgView.image=imgArray[indexPath.row]
        return cell
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        guard let flowLayout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return }

        flowLayout.itemSize = myCollectionView.frame.size

        flowLayout.invalidateLayout()

        myCollectionView.collectionViewLayout.invalidateLayout()
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        let offset = myCollectionView.contentOffset
        let width  = myCollectionView.bounds.size.width

        let index = round(offset.x / width)
        let newOffset = CGPoint(x: index * size.width, y: offset.y)

        myCollectionView.setContentOffset(newOffset, animated: false)

        coordinator.animate(alongsideTransition: { (context) in
            self.myCollectionView.reloadData()

            self.myCollectionView.setContentOffset(newOffset, animated: false)
        }, completion: nil)
    }
}

单元格类别:

class ImagePreviewFullViewCell: UICollectionViewCell, UIScrollViewDelegate {
    var scrollImg: UIScrollView!
    var imgView: UIImageView!

    override init(frame: CGRect) {
        super.init(frame: frame)

        scrollImg = UIScrollView()
        scrollImg.delegate = self
        scrollImg.alwaysBounceVertical = false
        scrollImg.alwaysBounceHorizontal = false
        scrollImg.showsVerticalScrollIndicator = true
        scrollImg.flashScrollIndicators()

        scrollImg.minimumZoomScale = 1.0
        scrollImg.maximumZoomScale = 4.0

        let doubleTapGest = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTapScrollView(recognizer:)))
        doubleTapGest.numberOfTapsRequired = 2
        scrollImg.addGestureRecognizer(doubleTapGest)

        self.addSubview(scrollImg)

        imgView = UIImageView()
        imgView.image = UIImage(named: "user3")
        scrollImg.addSubview(imgView!)
        imgView.contentMode = .scaleAspectFit
    }

    @objc func handleDoubleTapScrollView(recognizer: UITapGestureRecognizer) {
        if scrollImg.zoomScale == 1 {
            scrollImg.zoom(to: zoomRectForScale(scale: scrollImg.maximumZoomScale, center: recognizer.location(in: recognizer.view)), animated: true)
        } else {
            scrollImg.setZoomScale(1, animated: true)
        }
    }

    func zoomRectForScale(scale: CGFloat, center: CGPoint) -> CGRect {
        var zoomRect = CGRect.zero
        zoomRect.size.height = imgView.frame.size.height / scale
        zoomRect.size.width  = imgView.frame.size.width  / scale
        let newCenter = imgView.convert(center, from: scrollImg)
        zoomRect.origin.x = newCenter.x - (zoomRect.size.width / 2.0)
        zoomRect.origin.y = newCenter.y - (zoomRect.size.height / 2.0)
        return zoomRect
    }

    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return self.imgView
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        scrollImg.frame = self.bounds
        imgView.frame = self.bounds
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        scrollImg.setZoomScale(1, animated: true)
    }

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

我希望用户实际上可以在第一个视图控制器中选择图像,并在第二个视图控制器中分别显示该图像,也可以从那里向右或向左滑动并查看阵列中的其他图像,就像iOS Gallery应用程序一样。

0 个答案:

没有答案