Ios 某些tableview单元格内容在滚动后消失(swift)
下面是我的自定义单元格类:Ios 某些tableview单元格内容在滚动后消失(swift),ios,swift,uitableview,tableview,cell,Ios,Swift,Uitableview,Tableview,Cell,下面是我的自定义单元格类: 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:)")
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
}
}
这是一张您选择单元格时的照片:
这是同一个单元格的一张照片,向下滚动,看不见,然后向后滚动:
这里显然出了一些问题-我在自定义表视图单元格类中添加了“触摸”布尔值,假设单元格可能正在重新绘制,并且无法知道是否应该为该星形设置动画,因此它被视为零,但该修复似乎不起作用(也许我发现了一些问题,但实施不正确?)
如果您对这里发生的事情有任何线索,请告诉我!非常感谢!!!您的代码有各种问题。在您的
表视图(\ucode>cellForRowAt:)
方法中,您应该调用dequeueablereuseCell(标识符:for:)
您不应该试图从单元格中读取数据以加载内容。您应该将状态数据保存到某种类型的数据模型中。数组适用于具有单个分区的表视图,数组数组适用于分区表视图
有无数关于如何使用表视图的教程。你需要去读一些书。这里将其作为一个逐步的过程作为一个答案 1) 为数据创建结构
struct Profile {
var personName: String?
var photoURL: String?
var rank: String?
var isTouched: Bool?
// add init method and stuff
}
2) 使用这些配置文件元素填充阵列。因此,最终您将拥有一组配置文件
3) 使用此数组使用从概要文件对象获取数据的每个单元格元素填充tableview
4) 在cellForRowAt方法中,使用dequeueReusableCell(带标识符:for:)初始化单元格并赋值
5) 如果对于该特定配置文件,isTouched为true,则显示
cell.star.isFavorite = true
否则将其设置为false
6) 在didSelectRow中,获取indexpath.row,然后在配置文件数组中根据您对特定行的需要设置Profile.isTouched=true/false,并相应地进行切换。使用新的配置文件对象更新配置文件数组
7) 刷新tableview。这看起来像是典型的细胞回收错误
UITableView
在单元格离开屏幕时不会将其保留,而是将其循环使用。您不能将有效的模型数据存储在单元格中。理想情况下,您应该将接触的部分存储在数据存储中,而不是存储在单元格中。您的手机不用于存储任何信息。因此,每次单击单元格时,您都需要更新该特定项的数据存储,如touch==true,然后重新加载tableview。@kapsym当您说“更新该特定项的数据存储”时,是什么意思?所以您必须使用对象数组填充表视图,对吗?该对象数组是tableView的数据源。所以,如果你有一个自定义对象,它代表你在单元格中的信息,那么在该对象中添加一个参数。如果没有自定义对象,请创建一个具有名称、触摸等参数的对象。因此,当您进行此选择时,请从didselectCell方法获取indexpath.row,然后转到数组并更新该自定义对象的特定位置,即touch=true。和refresh tableview@S.Billings添加了这些步骤作为答案,为您指明了正确的道路。看看是否有用。我的tableview只有一个部分。因此是数组。好的,但是您的cellForRow(at:)
方法不会检查所选单元格的数组,以确定是否应将单元格设置为所选。除了不调用dequeueReusableCell(带有标识符:for:)
。