UITableView滚动后UITableViewCell自定义按钮图像显示不正确

时间:2015-01-08 13:54:30

标签: ios uitableview swift

我有UITableViewCells,它包含一个自定义按钮,这是一个图像。按下按钮时,图像会发生变化。但是,当我向上和向下滚动tableView时,被点击的单元格不再显示正确的图像,或者"轻触"图像显示在别处。我知道这个问题与出列并重复使用的细胞有关。我尝试做的是在我的自定义单元类中创建一个委托。委托调用tableViewController类中的方法。我正在用代码

这样做
self.delegate?.pressedButtonInCell?(self)

然而这不起作用..为什么?

=======自定义单元格类====

import UIKit
@objc protocol BoostCellDelegate{
optional func pressedButtonInCell(cell:BoostCell)
optional func displayAlert (title:String , error: String)
}
class BoostCell: UITableViewCell {
var delegate:BoostCellDelegate?
var boosted = false
var boostedButton = UIImage(named: "boostButtons.png")
@IBOutlet var userImage: UIImageView!
@IBOutlet var name: UILabel!

@IBOutlet var createdAt: UILabel!
@IBOutlet var boostButton: UIButton!
@IBAction func boostPressed(sender: UIButton) {

        let objectId = sender.titleLabel!.text!
        var query = PFQuery(className:"boostPost")
        query.getObjectInBackgroundWithId(objectId) {
            (boostPost: PFObject!, error: NSError!) -> Void in
            if error != nil {
                NSLog("%@", error)
                self.delegate?.displayAlert?("Something's gone wrong", error: "Might be the bad reception")
            } else {
                if boostPost != nil{
                    if boostPost["boostedBy"] != nil {
                        var boostedByArray : NSArray = boostPost["boostedBy"] as NSArray
                        if boostedByArray.containsObject(PFUser.currentUser().username){
                            println("username already boosted")

                        }
                        else{
                        var boostNumber = boostPost["boostNumber"] as Int
                        boostNumber++
                        boostPost["boostNumber"] = boostNumber
                        boostPost.addObject(PFUser.currentUser().username, forKey:"boostedBy")
                        boostPost.saveInBackground()
                        println("new username added to boosted")
                        self.delegate?.pressedButtonInCell?(self)
                        }
                    }
                    else if boostPost["boostedBy"] == nil{
                    var boostNumber = boostPost["boostNumber"] as Int
                    boostNumber++
                    boostPost["boostNumber"] = boostNumber
                    boostPost.addObject(PFUser.currentUser().username, forKey:"boostedBy")
                    boostPost.saveInBackground()
                    println("new username added to boosted")
                    self.delegate?.pressedButtonInCell?(self)

===================================== tableViewController类中的代码====== ===

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as BoostCell

    cell.name.text = userNewNames[indexPath.row]
    cell.content.text = userNewContent[indexPath.row]
    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    cell.createdAt.text = userCreatedAt[indexPath.row]
    cell.delegate = self

    if userBoostedBy[indexPath.row].count == 2 {
        cell.boostedBy.text = "1 boost"
    }
    else if userBoostedBy[indexPath.row].count > 2 {
        var count = userBoostedBy[indexPath.row].count - 1
        cell.boostedBy.text = "\(count) boosts"
    }
    else {
        cell.boostedBy.text = "0 boost"
    }

    if (userButtonState[indexPath.row] == true) {
        cell.boostButton.setImage(self.boostedButton, forState: UIControlState.Normal)
    }
    else {
        cell.boostButton.setImage(self.unBoostedButton, forState: UIControlState.Normal)
    }

    userImagesFiles[indexPath.row].getDataInBackgroundWithBlock({ (imageData:NSData!, error:NSError!) in
        if error == nil {
            let image = UIImage(data: imageData)
            cell.userImage.image = image
        }
    })
    cell.boostButton.setTitle(objectIds[indexPath.row], forState: UIControlState.Normal)
    func pressedButtonInCell(cell:BoostCell)
    {
        cell.boostButton.setImage(self.boostedButton, forState: UIControlState.Normal)
    }
    // function to display the alert message
    func displayAlert (title:String , error: String){
        var alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: {
            action in

        }))
        self.presentViewController(alert, animated: true, completion: nil)
    }
    return cell
}

1 个答案:

答案 0 :(得分:2)

您的cellForRowAtIndexPath方法似乎使用userButtonState[indexPath.row]来确定是否更改boostButton的图像。因此,您只需要修改pressedButtonInCell方法,为相关行设置userButtonState:

func pressedButtonInCell(cell:BoostCell)
{
    cell.boostButton.setImage(self.boostedButton, forState: UIControlState.Normal)
    if let indexPath = self.tableView.indexPathForCell(cell) {
        userButtonState[indexPath.row] = true
    }
}

(这假设self.tableView指向您的表视图;如果没有修改则提供正确的引用)。现在,当您按行上的按钮时,数组的相关元素将设置为true。如果该行然后滚出屏幕,当它再次向上滚动时,tableView:cellForRowAtIndexPath:方法将检查userButtonState,找到它为true,然后更新按钮的图像。相反,如果userButtonState为false,则重置图像(以防重新使用的单元格恰好具有boostedButton图像)。