首先,我是如何使用UIPicker创建可扩展单元格的。以防万一与问题相关。
通过此代码在UITableView中创建
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var identifyer = ""
switch(indexPath.row){
//other cells
case 1:
//Kategoria
identifyer = "category"
categoryCell = tableView.dequeueReusableCellWithIdentifier(identifyer) as? CategoryTableViewCell
categoryCell.pickerView.delegate = self
categoryCell.pickerView.dataSource = self
return categoryCell
//other cells
}
然后我必须认识到它是否被触及
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row == 1){
isCategoryCellSelected = true
tableView.reloadRowsAtIndexPaths([categoryIndexPath()], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
这就是我在UILabel
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
categoryCell.categoryNameLabel.text = categories[row]
}
当tableView刷新单元格
时最终override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch(indexPath.row){
case 1:
if (isCategoryCellSelected){
return CategoryTableViewCell.expandedHeight
} else {
return CategoryTableViewCell.defaultHeight
}
//other heights
}
}
Defalut细胞看起来
扩展的单元格外观
问题
因此,当我选择拾取器中的项目时,上面的标签应该更改它的文本并且正在发生。但是,当此单元格缩小到默认高度时,替换效果就消失了。我必须向下滚动才能看到只有这样我才能在标签中看到更改的文字。
我假设UITableView缓存此单元格,当单元格重新加载时,它将采用此缓存版本。我只是在猜测。这是我的想法吗?我怎样才能改变这种不必要的行为?
正如@the_critic所指出的那样,我在vars中保存细胞是完全错误的。同时每次选择行重新创建categoryCell都不是正确的方法。我最终以他创造细胞的方式,但我的方式是为细胞设定价值。
所以它看起来像是被谴责的:
创建单元格
categoryIdentifier为private let String
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell
switch(indexPath.row){
// other cells
case 1:
//Kategoria
print("recreate, selected category \(selectedCategory)")
let categoryCell = tableView.dequeueReusableCellWithIdentifier(categoryIdentifier) as! CategoryTableViewCell
categoryCell.pickerView.delegate = self
categoryCell.pickerView.dataSource = self
updateSelectedCategoryIfNeeded(categoryCell)
cell = categoryCell
// other cells
return cell;
}
private func updateSelectedCategoryIfNeeded(cell:CategoryTableViewCell) {
if let selectedCategory = self.selectedCategory{
// A category has been selected!
cell.categoryNameLabel.text = selectedCategory
updatePicekerRowPosition(cell)
}else{
// no category selected!
cell.categoryNameLabel.text = "Wybierz kategorie..."
}
}
private func updatePicekerRowPosition(cell:CategoryTableViewCell) {
if let index = categories.indexOf(selectedCategory!){
cell.pickerView.selectRow(Int(index.value), inComponent: 0, animated: false)
}
}
识别行选择
categoryIndexPath为private let NSIndexPath
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedCategory = categories[row]
if let categoryCell = tableView.cellForRowAtIndexPath(categoryIndexPath) as? CategoryTableViewCell {
categoryCell.categoryNameLabel.text = selectedCategory
}
}
答案 0 :(得分:1)
从我在代码中看到的内容中,您对表视图有很多误解。
我会试着更礼貌地说,但我不能。 您在代码中引用categoryCell的方式是完全错误的! UITableviewCell
如果您将它们出列,则不是静态引用!
第一步:删除categoryCell
变量!!!
表格视图的工作方式如下:
cellForRowAtIndexPath
方法从故事板或你的笔尖获取一个单元格,重复该单元格一遍又一遍!因此,在开始时,您可能会按照自己的方式(创建对categoryCell
的引用),但只要您有更多的单元格而不是适合屏幕,情况就会发生变化,因为变量将引用一个不同的细胞!
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell?
switch(indexPath.row){
//other cells
case 1:
//Kategoria
let identifier = "category"
// tableview checks if there is a cached cell
// for the identifier (reuse),
// if there is, it will take that one!
cell = tableView.dequeueReusableCellWithIdentifier(identifier) as! CategoryTableViewCell
cell.pickerView.delegate = self
cell.pickerView.dataSource = self
if let selectedCategory = self.selectedCategory{
// A category has been selected!
cell.categoryNameLabel.text = selectedCategory
}else{
// no category selected!
cell.categoryNameLabel.text = "Wybierz kategorie..."
}
return cell
//other cells
}
正如您在上面所看到的,我引入了一个名为selectedCategory
的新变量,它将反映当前选择的类别......
在控制器中设置如下:
var selectedCategory : String?
重新加载某个部分或行或整个表时会发生的情况是,再次调用给定行的所有UITableViewDataSource
方法!在某种程度上,表视图总是试图反映模型的某些状态。
您应该始终通过重新加载行/部分或整个表来反映模型中的更改(取决于更改的内容)。
因此,当您选择类别时,您可以更改模型并重新加载您的行!
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// update the model!
selectedCategory = categories[row]
// the table view now needs to know that the model changed!
// this will trigger the dataSource method cellForRowAtIndexPath
// and because it selectedCategory is now set, it will update
// your string accordingly!
tableView.reloadRowsAtIndexPaths([/*<IndexPath of your categoryLabelCell>*/], withRowAnimation: UITableViewRowAnimation.Automatic)
}
唷!我希望有帮助...