Search code examples
iosswift3uicollectionviewxcode8

why is collection view header loading before viewdidload?


I am trying to add a activity indicator but I am not able to do so successfully because my collection view header is loading before viewdidload so therefore I have things showing before my activity indicator even starts. Can someone please help me or point me in the right direction. I have posted my code below

viewDidLoad

 override func viewDidLoad() {
        super.viewDidLoad()

           fetchUser()
   profileCollectionView?.register(guestHeaderCollectionViewCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerId")

   profileCollectionView?.register(photoViewCollectionViewCell.self, forCellWithReuseIdentifier: cellId)

}

   func fetchUser() {
        self.activityIndicator.startAnimating()

        if let uid = selectedUser.uid{

            Database.fetchUserWithUID(uid: uid) { (user) in
                self.selectedUser = user
                self.navigationItem.title = self.selectedUser?.fullName

                self.profileCollectionView?.reloadData()
                self.activityIndicator.stopAnimating()
                self.activityIndicator.isHidden = true
                self.fetchOrderedPosts()
            }
        }
    }

Collection view header thats being called before viewDidLoad

 func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
       let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerId", for: indexPath) as! guestHeaderCollectionViewCell

        header.user = self.selectedUser
        header.delegate = self

        return header
    }

view controller

class newGuestPhotoViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, guestProfileHeaderDelegate, HomePostCellDelegate {

    let cellId = "cellId"
    let homePostCellId = "homePostCellId"

    @IBOutlet weak var profileCollectionView: UICollectionView!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!

    var user: userAccount?
    var selectedUser: userAccount!
    var posts = [Post]()    
    let stringID = NSUUID().uuidString   
    var isGridView = true

    func didChangeToGridView() {
        isGridView = true
        profileCollectionView?.reloadData()
    }

    func didChangeToListView() {
        isGridView = false
        profileCollectionView?.reloadData()
    }

    var showDataFlag : Bool = false!

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchUser()
        profileCollectionView?.register(guestHeaderCollectionViewCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerId")       
        profileCollectionView?.register(photoViewCollectionViewCell.self, forCellWithReuseIdentifier: cellId)       
        profileCollectionView?.register(newsfeedCollectionViewCell.self, forCellWithReuseIdentifier: homePostCellId)
    }  
    func fetchUser() {
        self.activityIndicator.startAnimating()
        if let uid = selectedUser.uid{

            Database.fetchUserWithUID(uid: uid) { (user) in
                self.selectedUser = user
                self.navigationItem.title = self.selectedUser?.fullName
                self.showDataFlag = true;
                self.profileCollectionView?.reloadData()
                self.activityIndicator.stopAnimating()
                self.activityIndicator.isHidden = true
                self.fetchOrderedPosts()
            }
        }
    }

    fileprivate func fetchOrderedPosts() {
        guard let uid = selectedUser?.uid else { return }
        let ref = Database.database().reference().child("post").child(uid)
        ref.queryOrdered(byChild: "dateOfPost").observe(.childAdded, with: { (snapshot) in            
            guard let dictionary = snapshot.value as? [String: Any] else { return }            
            let uid = dictionary["postUserUID"] as? String

            Database.fetchUserWithUID(uid: uid!, completion: { (userSnap) in

            let post = Post(user:userSnap, dictionary: dictionary)           
            self.posts.insert(post, at: 0)
            guard let uid = Auth.auth().currentUser?.uid else {return}
            Database.database().reference().child("likes").child(post.postID!).child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
                print(snapshot)

                if let value = snapshot.value as? Int, value == 1 {
                    post.hasLiked = true
                } else {
                    post.hasLiked = false
                }

              DispatchQueue.main.async(execute: {
            self.profileCollectionView?.reloadData()
                })
            }, withCancel: { (err) in
                print("Failed to fetch like info for post:", err)
            })

            })
        }) { (err) in
            print("Failed to fetch ordered posts:", err)
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if(!showDataFlag){
            return 0
        }
        return posts.count
    }

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

        if isGridView {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! photoViewCollectionViewCell
            cell.post = posts[indexPath.item]

            return cell
        } else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: homePostCellId, for: indexPath) as! newsfeedCollectionViewCell
            cell.post = posts[indexPath.item]
            cell.delegate = self

            return cell
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
       let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerId", for: indexPath) as! guestHeaderCollectionViewCell

        header.user = self.selectedUser
        header.delegate = self

        return header
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: view.frame.width, height: 250)
    }

Solution

  • As I said in mi comment, you can add a flag and after your fetchUser() you can set this flag true and your collectionView will show your data

    something like this

    var showDataFlag : Bool = false
    
    override func viewDidLoad() {
            super.viewDidLoad()
    
               fetchUser()
       profileCollectionView?.register(guestHeaderCollectionViewCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerId")
    
       profileCollectionView?.register(photoViewCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
    
    }
    
       func fetchUser() {
            self.activityIndicator.startAnimating()
    
            if let uid = selectedUser.uid{
    
                Database.fetchUserWithUID(uid: uid) { (user) in
                    self.selectedUser = user
                    self.navigationItem.title = self.selectedUser?.fullName
    
                    self.showDataFlag = true;
                    self.profileCollectionView?.reloadData()
                    self.activityIndicator.stopAnimating()
                    self.activityIndicator.isHidden = true
                    self.fetchOrderedPosts()
                }
            }
        }
    
    //In your Collection View Data Source Implementation
    
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            if(!showDataFlag){
               return 0
            }
               return yourNeededNumberOfSections
        }