在设置属性时,在我的自定义UITableViewCell
中,如果没有标签,则会创建标签并设置文本等。如果标签已存在,则不应执行任何操作。奇怪的是,当我第一次点击单元格时,它会创建应该是的标签。但是当我再次敲击细胞时,标签就会消失。我在一个干净的项目中重新创建了这个,同样的事情正在发生。造成这种奇怪行为的原因是什么?
CustomTableViewCell:
class TableViewCell: UITableViewCell {
var numberLabel: UILabel!
var views = [String: UILabel]()
var number: Int = 5 {
didSet {
println("AMOUNT: Accessed")
if numberLabel == nil {
println("AMOUNT: Amount is nil")
// Create amount label
numberLabel = UILabel()
if number > 0 { numberLabel.text = String(number) }
numberLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(numberLabel)
views["amount"] = numberLabel
// Amount label constraints
contentView.addConstraint(NSLayoutConstraint(item: numberLabel, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1, constant: 0))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[amount(40)]-8-|", options: nil, metrics: nil, views: views))
} else {
println("AMOUNT: Nothing should be changing or happening \n")
}
}
}
required init(coder aDecoder: NSCoder) {
fatalError("NSCoding not supported")
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
}
的ViewController:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
var items = [Int]()
var amount = 0
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 }
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as TableViewCell
cell.number = amount
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
amount++
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
编辑: 为了回应评论,我的控制台显示:
NUMBER: Accessed
NUMBER: Number is nil
NUMBER: Accessed
NUMBER: Number is nil << label shows "1"
NUMBER: Accessed
NUMBER: Nothing should be changing or happening << label disappears.
NUMBER: Accessed
NUMBER: Nothing should be changing or happening << label shows "1" again
NUMBER: Accessed
NUMBER: Nothing should be changing or happening << label disappears.
NUMBER: Accessed
NUMBER: Nothing should be changing or happening << label shows "1" again
NUMBER: Accessed
NUMBER: Nothing should be changing or happening << label disappears.
我还将背景更改为一种颜色,它就消失了。我想它与didSet的oldValue
有关。当我将值更改为willSet
时,newValue
也会发生同样的情况。当我使用&#34;旧值时,没有任何事情发生。虽然。
答案 0 :(得分:1)
不要对您的设置进行故障排除,而是让我指出其他内容:依靠标签&#34;在那里&#34;您实际上使用UI元素作为数据源。这违反了MVC(模型视图控制器)模式,可能会导致各种麻烦,包括您的情况。
我喜欢让桌面视图单元具有强大属性的机制,我可以像cellForRowAtIndexPath
中那样优雅地设置它。它产生简洁而美观的代码。它将数据逻辑与显示区分开,显示区在其所属的视图中编码。
因此,对于单元子类,我建议不要创建和销毁UI元素,因为这不是非常有效。相反,在storyboard中设置所需的所有UI元素,并在Interface Builder中将它们连接起来。在属性的setter中,检查number
属性的值并根据需要更改UI元素。如果要隐藏标签,请将其hidden
属性设置为true
。
理想情况下,表视图控制器应该知道索引路径上单元的状态。单元格应该只是正确显示这种状态。
答案 1 :(得分:1)
我认为这取决于重复使用相同的两个单元格:
您的表只有一行,但您最终会从头开始创建两个单元格,从初始输出中可以清楚地看到。它可能会创建两个,因为您在使用第一个单元格时重新加载,强制创建第二个单元格。
第一个单元格(A)的编号为0,空白标签。 第二个单元格(B)的编号为1,标签的编号为1。
当您执行下一个选择时,该表重用具有空白文本的单元格A.无论数字是多少,这都是空白的,因为您从未重置已经有标签的单元格的数字。
当您进行下一次选择时,该表将重复使用文本为1的单元格。
然后重复此模式,因为您在调用reload时总是使用一个单元格,而重新使用另一个单元格。因此A,B,A,B .....
要解决此问题,您需要在每次设置数字时设置标签内容。