How to make uicollectionview reload once it receiv

2019-02-20 21:50发布

I would like to make a UI collectionView reload itself after it has received data from firebase. Right now it only works manually when I click on the refresh button.

class MedalsViewController: UICollectionViewController {

    var imagesArray = [String]()
    var identities = [String]()
    var identities2 = [String]() //Creates an empty array
    var imagesArrayGreyed = [String]()
    var identities3 = [String]()
    let databaseRef = FIRDatabase.database().reference()
    let userID = FIRAuth.auth()?.currentUser?.uid

    override func viewDidLoad() {
        super.viewDidLoad()


        let userID = FIRAuth.auth()?.currentUser?.uid
        let databaseRef = FIRDatabase.database().reference()
        databaseRef.child("users").child(userID!).child("medals").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
            // Get user medals
            self.identities3 = snapshot.value as! [String]
            print (self.identities3)
        })


        imagesArray = ["1", "2", "3"] //Add all the medal images here
        identities = ["Shield", "Tie", "Star"] //Add all the identities here
        identities2 = ["Shield", "Tie"] //Choose what medals the user has.
        imagesArrayGreyed = ["1Greyed","2Greyed","3Greyed"] //Add all the greyed images here

    }

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

    override func viewWillAppear(animated: Bool) {

        self.tabBarController?.tabBar.hidden = false
        // Attempt at getting medals array from firebase database

    }



    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) 

        let imageView = cell.viewWithTag(1) as! UIImageView

        // Identites2 is the medals you currently own, so it'll check back to see if you own the medal and if not a question mark will be displayed. 
        // Time to check to see if it can update in real time. Check out firebase and try to link it here
        // Also see if can add a progress bar to only show for those greyed out medals 


        // Get ready to edit this to identities3 which is directly taken from firebase database
        if (identities3.contains(identities[indexPath.row])) {
            imageView.image = UIImage(named: imagesArray[indexPath.row])

        }
        else {
            imageView.image = UIImage(named: imagesArrayGreyed[indexPath.row]) //Set default image not in identities2
        }

        return cell

    }

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

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let vc = identities[indexPath.row]
        let viewController = storyboard?.instantiateViewControllerWithIdentifier(vc)
        self.navigationController?.pushViewController(viewController!, animated: true)
        viewController?.title = self.identities[indexPath.row]
    }


    // Send a fake medal from the array of identities2
    @IBAction func sendFakeMedalandReload(sender: UIBarButtonItem) {
        let databaseRef = FIRDatabase.database().reference()
        databaseRef.child("users/\(FIRAuth.auth()!.currentUser!.uid)/medals").setValue(identities2)
        self.collectionView!.reloadData()
    }
}

What this code does is basically display medals a user has by comparing two arrays (identities and identities3) to make sure they tally if not it will greyed out the images of identities no contained in the array (identities3)

The data is received in viewDidLoad as a snapshot data from firebase. I intend to make it such that the collectionView will reload every time when viewWillAppear is called.

I've attempted to call self.collectionView!.reloadData() in viewDidLoad and viewDidAppear but to no avail. I suspect it could be the delay in which data is received causing a blank array (identities3) to be loaded instead.

1条回答
聊天终结者
2楼-- · 2019-02-20 22:02

You need to call self.collectionView!.reloadData() after you have retrieved you data and stored it into your DataSource.

i.e in your completionBlock: of your Firebase .observeSingleEventOfType

databaseRef.child("users").child(userID!).child("medals").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        // Get user medals
        self.identities3 = snapshot.value as! [String]
        self.collectionView!.reloadData()
    })
查看更多
登录 后发表回答