首先,我是如何使用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
}
}
脱脂细胞外观
扩大的细胞外观
问题
因此,当我在选择器中选择项目时,上面的标签应将其更改为文本,并且这种情况正在发生。但是,当此单元格缩小到默认高度时,替换效果消失了。我必须上下滚动才能看到,然后才能看到标签中更改的文本。
我假设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
}
}
最佳答案
从您的代码中可以看到,您对表视图有很多误解。
我会尽量礼貌地说,但我不能。您在代码中引用categoryCell的方式是完全错误的!如果UITableviewCell
出队,则它们不是静态引用!
第一步:删除categoryCell
变量!!!
表格视图的工作方式如下:cellForRowAtIndexPath
方法从情节提要或您的笔尖中获取一个单元格,然后重复使用该单元格!因此,在一开始,您可能会按自己的方式进行操作(创建对categoryCell
的引用),但是一旦您的屏幕上的单元格过多,情况就会发生变化,因为变量将引用另一个单元格!
阅读建议:Creating and Configuring a Table View
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)
}
!希望对您有帮助...