Chris
Chris

Reputation: 2274

Swift - display UICollectionView after retrieving data

I have a collectionView that I fill by retrieving data from my Firestore Database. My problem is that I would like retrieve the data and only after finishing that the collectionView should appear with an animation being handled inside willDisplay.

This is how I retrieve my data:

func getWishlists() {
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser!.uid
    db.collection("users").document(userID).collection("wishlists").order(by: "listIDX").getDocuments() { ( querySnapshot, error) in
        if let error = error {
            print(error.localizedDescription)
        }else {
            // get all documents from "wishlists"-collection and save attributes
            for document in querySnapshot!.documents {
                let documentData = document.data()
                let listName = documentData["name"]
                let listImageIDX = documentData["imageIDX"]

                // if-case for Main Wishlist
                if listImageIDX as? Int == nil {
                    self.dataSourceArray.append(Wishlist(name: listName as! String, image: UIImage(named: "iconRoundedImage")!, wishData: [Wish](), color: self.mainColor))
                    // set the drop down menu's options
                    self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                    self.dropDownButton.dropView.dropDownListImages.append(UIImage(named: "iconRoundedImage")!)
                }else {

                    self.dataSourceArray.append(Wishlist(name: listName as! String, image: self.images[listImageIDX as! Int], wishData: [Wish](), color: self.customColors[listImageIDX as! Int]))

                    self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                    self.dropDownButton.dropView.dropDownListImages.append(self.images[listImageIDX as! Int])
                }

                // reload collectionView and tableView
                self.theCollectionView.reloadData()
                self.dropDownButton.dropView.tableView.reloadData()

            }
        }
        self.getWishes()
    }
}

I call getWishlists inside my viewDidLoad and this is how I handle my collectionView:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // return 1 more than our data array (the extra one will be the "add item" cell)
    return dataSourceArray.count + 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // if indexPath.item is less than data count, return a "Content" cell
    if indexPath.item < dataSourceArray.count {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContentCell", for: indexPath) as! ContentCell
        // set cell label
        cell.cellLabel.text = dataSourceArray[indexPath.item].name
        // set cell image
        cell.wishlistImage.image = dataSourceArray[indexPath.item].image          
        // set background color
        cell.imageView.backgroundColor = dataSourceArray[indexPath.item].color
        cell.wishCounterView.backgroundColor = dataSourceArray[indexPath.item].color
        cell.priceView.backgroundColor = dataSourceArray[indexPath.item].color



        cell.customWishlistTapCallback = {

            let heroID = "wishlistImageIDX\(indexPath)"
            cell.theView.heroID = heroID

            let addButtonHeroID = "addWishButtonID"
            self.addButton.heroID = addButtonHeroID     

            let vc = self.storyboard?.instantiateViewController(withIdentifier: "WishlistVC") as! WishlistViewController            

            vc.theTableView.tableView.reloadData()
            self.present(vc, animated: true, completion: nil)

        }

        return cell
    }

    // past the end of the data count, so return an "Add Item" cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AddItemCell", for: indexPath) as! AddItemCell

    // set the closure
    cell.tapCallback = {

        self.listNameTextfield.becomeFirstResponder()

        // let newListView appear
        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
            self.blurrImage.alpha = 0.96
            self.blurrImage.transform = CGAffineTransform(translationX: 0, y: 0)
            self.newListView.transform = CGAffineTransform(translationX: 0, y: 0)
            self.view.layoutIfNeeded()
        })

        self.appWillEnterForegroundHandler()

    }

    return cell

}

// animate displaying cells
func collectionView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Add animations here
    cell.alpha = 0

    UIView.animate(
        withDuration: 0.5,
        delay: 0.05 * Double(indexPath.row),
        animations: {
            cell.alpha = 1
    }) 
}

At the moment the cells are not being animated, instead they are just being displayed after a little bit of time when the data is retrieved.

Upvotes: 0

Views: 196

Answers (1)

Josh Homann
Josh Homann

Reputation: 16327

willDisplay is the correct place to pul the animation; however it only fires if you set the delegate. It looks like you se the datasource or you wouldn't see anything. Set the delegate and breakpoint willDisplay to verify its being called.

Upvotes: 2

Related Questions