简体   繁体   中英

Displaying an array in a table view before the user see it

I am working on pulling in data from firebase and displaying it in a table view. I populate an array with the data received and use the array to fill the tableview, however the data is not being displayed.

I realized the issue is that the tableview is loading before the array gets populated. I've attempted putting a reloadData in viewdidload but this makes the data pop in after it is displayed and does not look clean.

How can I get the tableview to load the data before the view appears so that the transition is smooth?

This code is inside my viewdidload method :

let categoryRef = Database.database().reference().child("category/\(category)")
    let user = Auth.auth().currentUser
    if let user = user {
        let uid = user.uid
        categoryRef.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChildren(){
                for child in (snapshot.value as? NSDictionary)! {
                    if let object = child.value as? [String:AnyObject]{
                        let name = object["name"] as! String
                        self.nameArray.append(name)
                        self.categoryDict["\(name)"] = child.key as! String
                    }

                }
            }

        })
    }

}

Try reloading the data just after you appended all the children:

let categoryRef = Database.database().reference().child("category/\(category)")
    let user = Auth.auth().currentUser
    if let user = user {
        let uid = user.uid
        categoryRef.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChildren(){
                for child in (snapshot.value as? NSDictionary)! {
                    if let object = child.value as? [String:AnyObject]{
                        let name = object["name"] as! String
                        self.nameArray.append(name)
                        self.categoryDict["\(name)"] = child.key as! String
                    }

                }
                self.tableView.reloadData()
            }

        })
    }

}

Call func insertSections(IndexSet, with: UITableViewRowAnimation) instead but remember to wrap it inside a call to beginUpdates and endUpdates . Also make sure your updating your UI on the main queue.

because

categoryRef.observeSingleEvent

is asynchronous, you should reload the table view after the block finishes, the way @barbarity proposes.

If you want a smoother transition, start this call

let categoryRef = Database.database().reference().child("category/\(category)")

before presenting your viewController, set the array and then present it.

But the practice in most of the cases with asynchronous processing is, start loading the data on viewDidLoad and have a UI loading mechanism (spinner)

I guess you could make other views which will make you sense the feeling of 'data pop' showed after the data is ready.

On the extreme condition, you may try to hide the whole tableview or even show Activity Indicator on the screen, then show the tableview and hide indicator after the datas for tableview is ready (In Objective-C):

- (void)viewDidLoad {

    //do init work ...

    self.tableview.hidden = YES;
    [self showIndicator];
    [self requestDataFinish:^{
          self.tableview.hidden = NO;
          [self hideIndicator];
          [self.tableview reload];
    }];        

}

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