我在app中使用了tableview,我在其中使用了分页。请求被发送到服务器,它返回大小为10的批量项目。一切正常,直到现在。现在我在tableview单元格中有一个imageview(自定义)。我希望当用户点击它时,该图像视图的图像会切换。我用以下方式尝试了这件事:
TableviewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell : AdventureTableViewCell = tableView.dequeueReusableCell(withIdentifier: "adventureCell" , for: indexPath) as? AdventureTableViewCell else {
fatalError("The dequeued cell is not an instance of AdventureViewCell.")
}
cell.adventureName.text = adventureList[indexPath.row]
cell.amountLabel.text = "\(adventurePriceList[indexPath.row])$"
cell.favouriteButtonHandler = {()-> Void in
if(cell.favouriteButton.image(for: .normal) == #imageLiteral(resourceName: "UnselectedFavIcon"))
{
cell.favouriteButton.setImage(#imageLiteral(resourceName: "FavSelectedBtnTabBar"), for: .normal)
}
else
{
cell.favouriteButton.setImage(#imageLiteral(resourceName: "UnselectedFavIcon"), for: .normal)
}
}
}
CustomCell:
class AdventureTableViewCell: UITableViewCell {
@IBOutlet weak var adventureName: UILabel!
@IBOutlet weak var adventureImage: UIImageView!
@IBOutlet weak var amountLabel: UILabel!
@IBOutlet weak var favouriteButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
var favouriteButtonHandler:(()-> Void)!
var shareButtonHandler:(()-> Void)!
override func awakeFromNib() {
super.awakeFromNib()
adventureName.lineBreakMode = .byWordWrapping
adventureName.numberOfLines = 0
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func prepareForReuse() {
adventureImage.af_cancelImageRequest()
adventureImage.layer.removeAllAnimations()
adventureImage.image = nil
}
@IBAction func favouriteButtonTapped(_ sender: Any) {
self.favouriteButtonHandler()
}
现在我遇到的问题是,如果用户在任何一个单元格上点击第一个图像视图,它就会改变它的图像,但是每个第四个单元格都会改变它的图像。 例如,如果我已经点击了第一个单元格的图像视图,则其图像被更改,但是单元格5,9,13的图像也会被更改。
我的代码出了什么问题?我错过了什么吗?由于分页,indexPath.row存在一些问题,但我不知道它究竟是什么以及如何解决它。我发现了一个类似的问题,但其公认的解决方案对我没有用,所以任何帮助都会受到赞赏。
答案 0 :(得分:0)
如果您需要切换图像并且滚动后也应该处于最后一个切换状态意味着您需要使用数组来存储索引位置并通过比较cellfoeRowAtIndex
内的索引位置和滚动状态来切换状态最后一个切换状态,即使滚动tableview也是保留最后一个切换索引的可能方法之一,否则你将丢失最后一个切换位置
if self.toggleStatusArray[indexPath.row]["toggle"] as! String == "on"{
cell.favouriteButton.setImage(#imageLiteral(resourceName: "FavSelectedBtnTabBar"), for: .normal)
} else {
cell.favouriteButton.setImage(#imageLiteral(resourceName: "UnselectedFavIcon"), for: .normal)
}
cell.favouriteButtonHandler = {()-> Void in
if self.toggleStatusArray[indexPath.row]["toggle"] as! String == "on"{
//Assign Off status to particular index position in toggleStatusArray
} else {
//Assign on status to particular index position in toggleStatusArray
}
}
希望这会对你有所帮助
答案 1 :(得分:0)
你的代码看起来不错,我只看到一个大错误。
当您设置动态数据(名称,图片,随时更改的内容)时,请使用func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)
而非cellForRowAt indexPath
。
cellForRowAt indexPath
应该用于静态资源和单元注册。
如果你在iOS 10上+看看prefetchDataSource
会加速战利品,我喜欢它。
https://developer.apple.com/documentation/uikit/uitableview/1771763-prefetchdatasource
小例子:
这里你注册单元格,并设置表格视图中所有单元格的所有常用内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "adventureCell" , for: indexPath)
cell.backgroundColor = .red
return cell
}
这里调整所有特定于对象的东西
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.nameLabel.text = model[indexPath.row].name
// also all the specific UI stuff goes here
if model[indexPath.row].age > 3 {
cell.nameLabel.textColor = .green
} else {
cell.nameLabel.textColor = .blue
}
}
你需要这个,因为单元格被重用,并且它们有自己的生命周期,所以你想尽可能晚地设置特定的数据,但是你想要尽可能少地设置通用数据(你可以做的大多数事情)一旦在单元初始化。)
Cell init也是通用数据的好地方,但你不能把所有内容都放在那里
此外,关于单元格willDisplay
的好处是你知道那时帧的实际大小