简体   繁体   中英

iOS swift tableview cell for parse query data

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
    var query = PFQuery(className:"category")
    let object = objects[indexPath.row] as String  

    query.whereKey("type", equalTo:"DRUM")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            for object in objects {
                NSLog("%@", object.objectId)
                let abc = object["link"]
                println("the web is \(abc)")

            cell.textLabel!.text = "\(abc)"
            }
        } else {
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }
    return cell
}

截图 after add the let object = objects[indexPath.row] as String can't load the view, delete the line show only one row successfully.

First I advise you to get your cell data outside cellForRowAtIndexPath. This function is not a good place to receive data from parse. Make another function and create a class variable and put handle getting data from there.

let object = objects[indexPath.row] as String  
for object in objects 

Try not to use same variable names for different stuff, as they will confuse you.

This line is not contributing to anything at the moment it seems. Try deleting it:

let object = objects[indexPath.row] as String  

First lets have principles in mind. Don't ever update UI from a separate thread, its behavior is unexpected or undefined. It works or works weird.

Second, the problem you have is the when the VC gets loaded the tableView's datasource is called there and then on the main thread. Now you tried to add something on the cell by doing a Async call in separate thread which will take time and main thread is not waiting when the call to parse is being done. If you have difficulty in Async please take a look at the documentation its really important to get a good grasp of the few terms and the principles.

The thing is your main thread runs top to bottom without waiting each call to server thats async in the cell generation. So the result of that call will post later on and you are not posting on main thread too.

Moreover, i would suggest you don't do this approach for big projects or manageable code base. I generally do is:

  1. when the view loads call the Parse with the needed information
  2. Wait for that on a computed variable which i will observe to reload table views once I'm conformed i have the data.
  3. Initially table view will have 0 rows and thats fine. Ill make a spinner dance during that time.

I hope i made some issues clear. Hope it helps you. Cheers!

 //a computed var that is initialized to empty array of string or anything you like
//we are observing the value of datas. Observer Pattern.
var datas = [String](){
    didSet{
        dispatch_async(dispatch_get_main_queue(), {
            //we might be called from the parse block which executes in seperate thread
            tableView.reloadData()
        })
    }
}

func viewDidLoad(){
    super.viewDidLoad()
    //call the parse to fetch the data and store in the above variable 
    //when this succeeds then the table will be reloaded automatically
    getDataFromParse()
}


//get the data: make it specific to your needs
func getDataFromParse(){
    var query = PFQuery(className:"category")
    //let object = objects[indexPath.row] as String         //where do you use this in this block
    var tempHolder = [String]()

    query.whereKey("type", equalTo:"DRUM")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in
        if error == nil && objects != nil {
            for object in objects!{
                //dont forget to cast it to PFObject
                let abc = (object as! PFObject).objectForKey("link") as? String ?? ""   //or as! String
                println("the web is \(abc)")
                tempHolder.append(abc)
            }
        } else {
            print("error")  //do some checks here
        }
    }
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
    cell.textLabel!.text = datas[indexPath.row]
    return cell
}

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