Reputation: 123
Essentially, I have built a tableviewcontroller
with a PFQuery
to load information for each individual cell and store it in a array. There are two calls to parse, one to store usernames into an array, and another one to check if the current user is "following" them.
var query = PFUser.query()
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
self.users.removeAll(keepCapacity: true) // users is an array declared globally
for object in objects {
var user:PFUser = object as PFUser
var isFollowing:Bool
if user.username != PFUser.currentUser().username {
self.users.append(user.username)
isFollowing = false
var query = PFQuery(className:"followers")
query.whereKey("follower", equalTo:PFUser.currentUser().username)
query.whereKey("following", equalTo:user.username)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
for object in objects {
isFollowing = true
}
self.following.append(isFollowing)
self.tableView.reloadData()
} else {
// Log details of the failure
println(error)
}
}
}
}
}
If I call reloadData()
at another place, the table will not display correctly. This makes my table loading inefficient..since the table reloads with every check for the "isfollowing" variable. How would I make it reload only once? After all the "isfollowing" variable have been appended? Can you please outline the solution step by step so I can get a general sense of direction and what to learn.
EDIT2:
In the code above I query to check which users the currentUser is following. If they are following them, I append "true" to the array "following". The code below is what I'm doing to checkmark the tableviewcells to show that they are following other users. With my original code, all the cells become checkmarked after scrolling up and down a couple of times, why?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
if following.count > indexPath.row {
if following[indexPath.row] == true {
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
}
}
cell.textLabel.text = users[indexPath.row]
return cell
}
EDIT: Wrong code posted originally.
Upvotes: 0
Views: 992
Reputation: 6377
Use findObjects
to call synchronously and put it in our own queue may helps.
// queue is declared as an instance property
let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)
var query = PFUser.query()
dispatch_async(queue) {
dispatch_async(dispatch_get_main_queue()) {
self.users.removeAll(keepCapacity: true) // users is an array declared globally
}
for user in query.findObjects() as [PFUser] {
var isFollowing = false
if user.username != PFUser.currentUser().username {
dispatch_async(dispatch_get_main_queue()) {
self.users.append(user.username)
}
var query = PFQuery(className:"followers")
query.whereKey("follower", equalTo:PFUser.currentUser().username)
query.whereKey("following", equalTo:user.username)
// call findObjects synchronously
if let objects = query.findObjects() {
if !objects.isEmpty {
isFollowing = true
}
dispatch_async(dispatch_get_main_queue()) {
self.following.append(isFollowing)
}
}
}
}
// notify table view to reload
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
}
You can create a UITableViewCell subclass and override its prepareForReuse
to reset accessoryType
.
class MyTableView: UITableViewCell {
override func prepareForReuse() {
accessoryType = .None
}
}
In your code, you didn't handle the case for following[indexPath.row] != true
. If you don't want to subclass UITableViewCell, you can also reset the checkmark there.
Upvotes: 2