UITableView 滚动后 UITableViewCell 自定义按钮图像显示不正确
UITableViewCell custom button image displaying incorrectly after UITableView scrolling
我有一个包含自定义按钮的 UITableViewCells,它是一个图像。按下按钮时,图像会发生变化。但是,当我上下滚动 tableView 时,点击的单元格不再显示正确的图像,或者 "tapped" 图像显示在其他地方。我知道这个问题与出列和重用的单元格有关。我试图做的是在我的自定义单元格 class 中创建一个委托。委托调用 tableViewController class 中的方法。我正在使用代码
self.delegate?.pressedButtonInCell?(self)
但是这不起作用..为什么?
=======自定义单元格class====
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 中的代码 class =========
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
}
您的 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
指向您的 table 视图;如果没有修改以提供正确的参考)。现在,当您按下一行上的按钮时,数组的相关元素将设置为 true
。如果该行然后滚出屏幕,当它再次滚动回来时,tableView:cellForRowAtIndexPath:
方法将检查 userButtonState
,发现它是 true
并因此更新按钮的图像。相反,如果 userButtonState 为假,图像将被重置(以防万一重新使用的单元格恰好有 boostedButton
图像)。
我有一个包含自定义按钮的 UITableViewCells,它是一个图像。按下按钮时,图像会发生变化。但是,当我上下滚动 tableView 时,点击的单元格不再显示正确的图像,或者 "tapped" 图像显示在其他地方。我知道这个问题与出列和重用的单元格有关。我试图做的是在我的自定义单元格 class 中创建一个委托。委托调用 tableViewController class 中的方法。我正在使用代码
self.delegate?.pressedButtonInCell?(self)
但是这不起作用..为什么?
=======自定义单元格class====
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 中的代码 class =========
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
}
您的 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
指向您的 table 视图;如果没有修改以提供正确的参考)。现在,当您按下一行上的按钮时,数组的相关元素将设置为 true
。如果该行然后滚出屏幕,当它再次滚动回来时,tableView:cellForRowAtIndexPath:
方法将检查 userButtonState
,发现它是 true
并因此更新按钮的图像。相反,如果 userButtonState 为假,图像将被重置(以防万一重新使用的单元格恰好有 boostedButton
图像)。