简体   繁体   中英

Swift 4: UITableViewCell does will not display data upon initial load, but will load on second load

I have ran into a very interesting problem in my application. Upon viewing the users profile page the data in my tableview is being pulled and printed into the console, the problem though is that my information will not load into my tablecell.

If i were to leave the current tab and then go back to the profile page my data will then be loaded. I am using firebase in order to pull my information down.

I would like for the data to be there upon the first time viewing the page.

ProfileViewController

    var cellId = "cell"
    var userGames = [Game]()
    var userCurrentGames = [Any]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        tableView.register(ProfileGameCell.self, forCellReuseIdentifier: cellId)

    //I CALL MY FUNCTIONS UPON FIRST LOAD
        getCurrentUser()
        getUsersGames()

        }
    }

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

    //I CALL FUCTIONS EVERY TIME THE VIEW LOADS INCASE DATA CHANGES
        getCurrentUser()
        getUsersInformation()
        getUsersGames()

    }

    func getUsersGames() {
        let ref = Database.database().reference()
        let current = getCurrentUser()

//I FIND ALL THE GAMES IN THE USERS REF AND APPEND THEIR KEY TO THE ARRAY
            ref.child("users").child(current).child("user games").observe(.value, with: {(snapshot) in
                if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
                    self.userCurrentGames = []
                    for snap in snapshot {
                        let gameKey = snap.key

                        print("SNAPSHOT DATAAA: \(gameKey)")
                        self.userCurrentGames.append(gameKey)
                    }
                }
            })
            displayUsersGames()
    }

func displayUsersGames() {
    let ref = Database.database().reference()
    self.userGames = []
//I FIND ALL THE GAMES AND APPEND THEM TO THE ACTUAL GAME ARRAY
    for i in userCurrentGames {
        ref.child("games").child("\(i)").observeSingleEvent(of: .value, with: { (gameSnap) in
            if let gameDict = gameSnap.value as? Dictionary<String, AnyObject> {
                let key = gameSnap.key
                let game = Game(postKey: key, gameData: gameDict)
                self.userGames.append(game)

                self.tableView.reloadData()
            }
        })
    }
}

Table View Functions

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let game = userGames[indexPath.row]
    if let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? ProfileGameCell {
        cell.adminButton.tag = indexPath.row
        cell.configureUserGameCell(game: game)
        return cell
    } else {
        return ProfileGameCell()
    }
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return userGames.count
}

The problem is very clear:

observe works asynchronously – the result is returned later – so userCurrentGames is empty when displayUsersGames() is called.

A solution is to move displayUsersGames() into the completion block

...   
ref.child("users").child(current).child("user games").observe(.value, with: {(snapshot) in
        if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
            self.userCurrentGames = []
            for snap in snapshot {
                let gameKey = snap.key

                print("SNAPSHOT DATAAA: \(gameKey)")
                self.userCurrentGames.append(gameKey)
            }
            self.displayUsersGames()
        }
    })

Note:

Force downcast the cell

let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! ProfileGameCell

The code must not crash. If it does it reveals a design error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM