display collentionview from result of collectionview

108 views Asked by At

I have 2 collection views within 1 view controller. I want the 2nd collection view to display its contents based on the selection of an item in the first collectionview. Ive got it all working to the point where it gets the data to display but i think because the viewcontroller isn't reloading it isn't displaying the data (cell images, descriptions ect). how can i force refresh the view or is there a better way or showing the result in the 2nd collectionview?

full code for the class is below:

import UIKit
import Parse

private let reuseIdentifierPart = "CellPart"
private let reuseIdentifierPiece = "CellPiece"

class JourneyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    // passed packName from PackViewController
    var selectedPack: String!
    var selectedPart: String!

    @IBOutlet var collectionViewPart: UICollectionView!
    @IBOutlet var collectionViewPiece: UICollectionView!

    struct partStruct {
        var partName : String
        var partDescription : String
        var partTitle : String
        var partImage : PFFile
        var partID: String
    }

    struct pieceStruct {
        var pieceName : String
        //var pieceDescription : String
        //var pieceTitle : String
        var pieceImage : PFFile
    }

    var partArray = [partStruct]()
    var pieceArray = [pieceStruct]()

    var refreshView: UIViewController!


    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // if selected pack not nil
        //--------------------------------------------- PART DISPLAY IN COLLECTION ----
        if let partsToDisplay = selectedPack {
            let partQuery = PFQuery(className: "Part")
                //have to create PFObject from selectedPack
                partQuery.whereKey("fromPack", equalTo: PFObject(outDataWithClassName: "Pack", objectId: selectedPack))
                partQuery.findObjectsInBackground(block: { (objectsArray, error) in
                    if error != nil {
                        print(error!)
                    } else if let parts = objectsArray {
                        for object in parts {

                            let arrayName = object.object(forKey: "partName") as! String
                            let arrayDescription = object.object(forKey: "partDescription") as! String
                            let arrayTitle = object.object(forKey: "partTitle") as! String
                            let arrayImage = object.object(forKey: "partImage") as! PFFile
                            //let arrayPoint = object.object(forKey: "fromPack") as! String
                            let arrayID = object.objectId as String!
                            self.partArray.append(partStruct(partName: arrayName, partDescription: arrayDescription, partTitle: arrayTitle, partImage: arrayImage, partID: arrayID!))
                        }
                        self.partArray = self.partArray.sorted{ $0.partName < $1.partName }
                        self.collectionViewPart?.reloadData()
                    }
                })
        }

    }//viewwillappear

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if collectionView == self.collectionViewPart {
            //--------------------------------------------- PIECE DISPLAY IN COLLECTION ----
            print("I selected an item in the Parts stack")
            selectedPart = self.partArray[indexPath.item].partID
            print("i selected item \(selectedPart)")

            if let piecesToDisplay = selectedPart {
                let pieceQuery = PFQuery(className: "Piece")
                //have to create PFObject from selectedPack
                pieceQuery.whereKey("fromPart", equalTo: PFObject(outDataWithClassName: "Part", objectId: selectedPart))
                pieceQuery.findObjectsInBackground(block: { (objectsArray, error) in
                    if error != nil {
                        print(error!)
                    } else if let pieces = objectsArray {
                        print(objectsArray?.count)
                        for object in pieces {

                            let arrayName = object.object(forKey: "pieceName") as! String
                            let arrayImage = object.object(forKey: "pieceImage") as! PFFile

                            self.pieceArray.append(pieceStruct(pieceName: arrayName, pieceImage: arrayImage))
                        }
                        self.pieceArray = self.pieceArray.sorted{ $0.pieceName < $1.pieceName }
                        self.collectionViewPiece?.reloadData()
                    }
                })

            } else {
                // this is for selecting somehitng in the vertical stack
                print("WERE GOING TO GO TO THE NEXT SCREEN AND PLAY THE SOUND FILE")

            }
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == self.collectionViewPart {

            //pass this to the piece query when selected
            let selectedPart = self.partArray[indexPath.item].partName
            //--------------------------------------------- PART HOW TO DISPLAY EACH ITEM ----

            let cellPart: PartCollectionViewCell = collectionViewPart.dequeueReusableCell(withReuseIdentifier: reuseIdentifierPart, for: indexPath) as! PartCollectionViewCell

            //cellPart.labelCell.text = self.packArray[indexPath.item].packDescription
            //cellPart.labelCell.textColor = MyFunctions.UIColorFromHEX(hexValue: 0x0c1537)
            cellPart.imageCellPart.file = self.partArray[indexPath.item].partImage

            cellPart.imageCellPart.loadInBackground()

            cellPart.imageCellPart.layer.masksToBounds = true
            cellPart.imageCellPart.layer.cornerRadius = cellPart.imageCellPart.frame.height/2
            cellPart.imageCellPart.layer.borderWidth = 3
            cellPart.imageCellPart.layer.borderColor = MyFunctions.UIColorFromHEX(hexValue: 0x62aca2).cgColor

            return cellPart

        } else {
            //--------------------------------------------- PIECE HOW TO DISPLAY EACH ITEM ----

            let cellPiece: PieceCollectionViewCell = collectionViewPiece.dequeueReusableCell(withReuseIdentifier: reuseIdentifierPiece, for: indexPath) as! PieceCollectionViewCell

            //cellPiece.labelCell.text = self.packArray[indexPath.item].packDescription
            //cellPiece.labelCell.textColor = MyFunctions.UIColorFromHEX(hexValue: 0x0c1537)
            cellPiece.imageCellPiece.file = self.pieceArray[indexPath.item].pieceImage

            cellPiece.imageCellPiece.loadInBackground()

            cellPiece.imageCellPiece.layer.masksToBounds = true
            cellPiece.imageCellPiece.layer.cornerRadius = cellPiece.imageCellPiece.frame.height/2
            cellPiece.imageCellPiece.layer.borderWidth = 3
            cellPiece.imageCellPiece.layer.borderColor = MyFunctions.UIColorFromHEX(hexValue: 0x62aca2).cgColor

            return cellPiece
        }

    }
    // MARK: UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == self.collectionViewPart {
            return self.partArray.count
        } else {
            return self.pieceArray.count
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }


}//class
3

There are 3 answers

2
Vishnu gondlekar On

self.collectionViewPiece?.reloadData() should happen on main thread, because all the UI updates have to be done on main thread. Do it this way

DispatchQueue.main.async(execute: {
            self.collectionViewPiece?.reloadData()
        })

Have the above code in didSelectItemAt instead of just self.collectionViewPiece?.reloadData()

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if collectionView == self.collectionViewPart {
        //--------------------------------------------- PIECE DISPLAY IN COLLECTION ----
        print("I selected an item in the Parts stack")
        selectedPart = self.partArray[indexPath.item].partID
        print("i selected item \(selectedPart)")

        if let piecesToDisplay = selectedPart {
            let pieceQuery = PFQuery(className: "Piece")
            //have to create PFObject from selectedPack
            pieceQuery.whereKey("fromPart", equalTo: PFObject(outDataWithClassName: "Part", objectId: selectedPart))
            pieceQuery.findObjectsInBackground(block: { (objectsArray, error) in
                if error != nil {
                    print(error!)
                } else if let pieces = objectsArray {
                    print(objectsArray?.count)
                    for object in pieces {

                        let arrayName = object.object(forKey: "pieceName") as! String
                        let arrayImage = object.object(forKey: "pieceImage") as! PFFile

                        self.pieceArray.append(pieceStruct(pieceName: arrayName, pieceImage: arrayImage))
                    }
                    self.pieceArray = self.pieceArray.sorted{ $0.pieceName < $1.pieceName }
                    DispatchQueue.main.async(execute: {
            self.collectionViewPiece?.reloadData()
        })
                }
            })

        } else {
            // this is for selecting somehitng in the vertical stack
            print("WERE GOING TO GO TO THE NEXT SCREEN AND PLAY THE SOUND FILE")

        }
    }
}
7
Sri On

Please execute this from your main thread.

  self.collectionViewPiece?.reloadData()
  self.collectionViewPiece?.layoutIfNeeded();
0
WanderingScouse On

im not sure why, considering i had set both datasource and delegate within the storyboard however this fixed the problem.

override func viewDidLoad() {
    super.viewDidLoad()
    collectionViewPart.delegate = self
    collectionViewPiece.delegate = self
    collectionViewPart.dataSource = self
    collectionViewPiece.dataSource = self
}