滚动后某些表格视图单元格内容消失(swift)
Posted
技术标签:
【中文标题】滚动后某些表格视图单元格内容消失(swift)【英文标题】:Some tableview cell content disappears after scroll (swift) 【发布时间】:2017-07-17 13:38:29 【问题描述】:下面是我的自定义单元格类:
class AthleteTableViewCell: UITableViewCell
var myLabel1: UILabel!
var myLabel2: UILabel!
var profile: UIImageView!
var star = StarButton()
var touched = false
required init(coder aDecoder: NSCoder)
fatalError("init(coder:)")
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
let gap : CGFloat = 10
let labelHeight: CGFloat = 30
let labelWidth: CGFloat = 150
let lineGap : CGFloat = 5
let label2Y : CGFloat = gap + labelHeight + lineGap
myLabel1 = UILabel()
myLabel1.frame = CGRect(x: gap, y: gap, width: labelWidth, height: labelHeight)
myLabel1.textColor = UIColor.black
contentView.addSubview(myLabel1)
myLabel2 = UILabel()
myLabel2.frame = CGRect(x: gap * 5, y: label2Y, width: labelHeight, height: labelHeight)
myLabel2.textColor = UIColor.white
myLabel2.textAlignment = .center
myLabel2.backgroundColor = UIColor.flatMint()
myLabel2.layer.cornerRadius = 15.0
myLabel2.clipsToBounds = true
contentView.addSubview(myLabel2)
profile = UIImageView()
profile.image = UIImage()
profile.frame = CGRect(x: bounds.width - gap, y: bounds.height / 2, width: bounds.height * 1.25, height: bounds.height * 1.25)
profile.layer.cornerRadius = (bounds.height * 1.25) / 2
profile.layer.masksToBounds = true
contentView.addSubview(profile)
if (touched != false)
star.isSelected = true
star.frame = CGRect(x: gap, y: label2Y, width: labelHeight, height: labelHeight)
contentView.addSubview(star)
else
star.frame = CGRect(x: gap, y: label2Y, width: labelHeight, height: labelHeight)
contentView.addSubview(star)
star.isEnabled = true
以下是创建我的单元格的方法:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = AthleteTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "myCell")
cell.myLabel1.text = "\(myArray[indexPath.row])"
cell.myLabel1.textColor = UIColor.white
cell.myLabel2.isHidden = true
cell.profile.image = UIImage(named: cell.myLabel1.text!)
cellArray.append(cell)
if (cell.touched)
cell.star.isSelected = true
else
cell.star.isOpaque = true
cell.backgroundColor = UIColor(white: 1, alpha: 0.2)
return cell
下面是选择一个单元格的方法,该单元格会触发一个动画,我希望它的最终状态保留在 tableview 单元格上。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
makeSelection(tableView, didSelectRowAt: indexPath)
func makeSelection(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let cell = tableView.cellForRow(at: indexPath) as! AthleteTableViewCell
cell.selectionStyle = UITableViewCellSelectionStyle.none
if(selectionArray.contains(myArray.object(at: indexPath.row)))
//Popping selection off of the stack and updating all labels
updateLabels(tableView: tableView)
selectionArray.remove(myArray[indexPath.row])
cell.star.isFavorite = false
cell.myLabel2?.isHidden = true
//need to somehow implement all of the rank labels decreasing by one if I deselect someone
cell.touched = false
//updateLabels(tableView: tableView)
else
selectionArray.add(myArray[indexPath.row])
cell.touched = true
let rank = selectionArray.count
cell.myLabel2.isHidden = false
cell.myLabel2?.text = "\(rank)"
cell.star.isFavorite = true
这是您选择单元格时的照片:
这是同一个单元格在向下滚动后的照片,这样就看不见了,然后再向后滚动:
这里显然出了点问题 - 我在自定义表格视图单元格类中添加了“已触摸”布尔值,假设单元格可能正在重绘,并且无法知道是否应该让该星形动画或者不是,所以它被认为是 nil,但该修复似乎不起作用(也许我正在做某事但实施不正确?)
如果您知道这里发生了什么,请告诉我!非常感谢!!!
【问题讨论】:
这看起来像经典的细胞回收错误。UITableView
不在屏幕外时不会保留细胞,而是将它们回收再利用。您无法将有效模型数据存储在单元格中。
理想情况下,您应该将触摸的部分存储在数据存储区而不是单元格中。您的手机不用于存储任何信息。因此,每次单击您的单元格时,您都需要为该特定项目更新数据存储区,说 touch == true,然后重新加载 tableview。
@kapsym 当你说“为那个特定项目更新你的数据存储”时,你是什么意思?
所以您必须使用对象数组来填充您的表格视图,对吧?该对象数组是 tableView 的数据源。因此,如果您有一个自定义对象来表示您的信息,请在该对象中添加touched 参数。如果您没有自定义对象,请创建一个具有名称、触摸等作为参数的对象。因此,当您进行此选择时,从 didselectCell 方法中获取 indexpath.row,然后转到您的数组并更新该特定位置的自定义对象,说 touch = true。并刷新tableview
@ S.Billings 添加了这些步骤作为答案,为您指明了正确的道路。看看有没有帮助。
【参考方案1】:
您的代码存在各种问题。在您的tableView(_:cellForRowAt:)
方法中,您应该调用dequeueReusableCell(withIdentifier:for:)
。
您不应尝试从单元格中读取数据以加载内容。您应该将状态数据保存到某种数据模型中。数组适用于具有单个部分的表视图,数组数组适用于分段表视图。
关于如何使用表格视图的教程数不胜数。你需要去读一读。
【讨论】:
我的 tableview 确实有一个部分。因此数组。 好的,但是您的cellForRow(at:)
方法不会检查您的选定单元格数组,以查看它是否应该将单元格设置为选定的。除了不打电话给dequeueReusableCell(withIdentifier:for:)
。【参考方案2】:
这里将其作为一个逐步的过程提及它作为答案
1) 为您的数据创建结构
struct Profile
var personName: String?
var photoURL: String?
var rank: String?
var isTouched: Bool?
// add init method and stuff
2) 使用这些 Profile 元素填充您的数组。这样最终你就有了一个配置文件数组。
3) 使用此数组来填充您的表格视图,其中每个单元格元素都从 Profile 对象中获取数据。
4) 在您的 cellForRowAt 方法中使用 dequeueReusableCell(withIdentifier:for:) 来初始化您的单元格并分配值
5) 如果对于该特定配置文件,isTouched 为真,则显示
cell.star.isFavorite = true
否则设置为假
6) 在您的 didSelectRow 中,获取 indexpath.row,然后在您的配置文件数组中根据您对该特定行的需要设置 Profile.isTouched=true/false 并相应地切换。使用新的配置文件对象更新您的配置文件数组。
7) 刷新表格视图。
【讨论】:
以上是关于滚动后某些表格视图单元格内容消失(swift)的主要内容,如果未能解决你的问题,请参考以下文章
Swift:每次重新加载时都会一次又一次地添加表格视图单元格内容?