简体   繁体   中英

Swift/Parse: Elements in table view cell with nil value displaying values from other cells

My project has a table view (specifically a PFQueryTableView as I'm using Parse for my backend), which displays either text or a picture (in addition to some standard elements like the poster's profile picture and name). Think of this as a Facebook-like feed where posts can either contain text or an image. This means that in my "Yell" class (posts), either the "yellText" (text in post) or the "pictureFromCamera" (picture in post) value will be nil. These are loaded into a custom table view cell (prototype cell) containing a label for the text, and a PFImageView for the images. This allows me to change the formatting of the cell using if/else statements depending on whether or not the "postText" or the "postImage" for the given cell is nil. This works when I open the view controller, and it looks like this:

在此处输入图片说明

When I use the pull to refresh function, the images are placed in cells in which they are not meant to be:

在此处输入图片说明

And this is what the my object looks like in Parse:

在此处输入图片说明

My code for the container view containing the PFQueryTableView is as follows:

class YellContentTableViewController: PFQueryTableViewController {

var posterFirstName: String!
var hasUpvoted: Bool?

// Initialise the PFQueryTable tableview
override init(style: UITableViewStyle, className: String!) {
    super.init(style: style, className: className)


}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    // Configure the PFQueryTableView
    self.parseClassName = "Yell"
    self.textKey = "yellText"
    self.pullToRefreshEnabled = true
    self.paginationEnabled = true
    if (self.paginationEnabled == true){
      self.objectsPerPage = 20
    }
}


// Define the query that will provide the data for the table view
override func queryForTable() -> PFQuery {
    var query = PFQuery(className: "Yell")
    query.orderByDescending("createdAt")


    return query
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomTableViewCell!
    if cell == nil {
        cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CustomCell")
    }

          if let posterFirstName = object?["posterFirstName"] as? String {
        cell.customPosterFirstName.text = posterFirstName
    }

     //Display poster's profile picture
    var initialThumbnail = UIImage(named: "Temporary")
    cell.customPosterProfilePicture.image = initialThumbnail
    if let thumbnail = object?["posterProfilePicture"] as? PFFile {
        cell.customPosterProfilePicture.file = thumbnail
        cell.customPosterProfilePicture.loadInBackground()
    }

    if let score = object?.valueForKey("voteCount") as? Int {
    cell.yellVotes.text = "\(score)"

    }


     let yellText = object?["yellText"] as? String
    if (yellText == "a"){
    cell.customYellText.text = ""
    var pictureFromCamera = object?["pictureFromCamera"] as? PFFile

         tableView.rowHeight = 90
            cell.customPictureFromCamera.file = pictureFromCamera
            cell.customPictureFromCamera.loadInBackground()

    }

    if (yellText != "a"){
     tableView.rowHeight = 60
    if let yellText = object?["yellText"] as? String {
        cell.customYellText.text = yellText
         cell.customPictureFromCamera.file = nil
    }

    }


    return cell
}

And for the prototype cell:

class CustomTableViewCell: PFTableViewCell {

@IBOutlet weak var customPictureFromCamera: PFImageView!
@IBOutlet weak var customYellText: UILabel!
@IBOutlet weak var customPosterFirstName: UILabel!
@IBOutlet weak var customPosterProfilePicture: PFImageView!

These outlets are connected to imageViews and labels in a prototype cell in the storyboard.

As you may notice, the determinant of whether or not the CustomTableViewCell is formatted as being a picture cell or a text cell is an if/else statement regarding whether or not yellText == A. At first this was based on an if/else statement regarding if customPictureFromCamera == nil. When I did that however, yellTexts from other cells would be entered into picture cells (where the yellText element in the Parse object is undefined/nil). My quick and dirty solution to this was to set yellText as "a" for all picture posts ("Yells"), set the if/else statement to depend of if yellText == "a", and if yes, set yellText = "" so that no text shows in the picture cells. This works, but is obviously not an elegant solution. I considered a similar approach for my picture issue (uploading a small file to the pictureFromCamera element in the Parse object so that it is no longer set to undefined/nil), but it would be terribly inefficient, so I'm hoping to find a better solution.

So, does anyone have any idea as to why refreshing the PFQueryTableView leads nil values for a given cell being replaced by values from other cells?

One way to solve the problem is to implement func prepareForReuse() in your table cell class such that it resets all elements of the cell to reasonable values. That way, you can be sure that each cell is cleared out before it's reused, so old values won't show up.

Another option is to ensure that you set every element of the cell in your tableView(_ tableView:,cellForRowAtIndexPath:) method. This is reasonable if you're not using a custom cell class, for example.

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