gpt4 book ai didi

ios - UITableView 在重新加载后重置 UITableViewCell

转载 作者:行者123 更新时间:2023-11-29 01:39:41 25 4
gpt4 key购买 nike

首先,我如何使用 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]

展开的单元格外观

[expanded]

问题

所以当我在选择器中选择项目时,上面的标签应该更改它的文本并且正在发生。但是,当此单元格缩小到默认高度时,替换效果就消失了。我必须向下和向上滚动才能看到,只有这样我才能在标签中看到更改的文本。

我假设 UITableView 缓存了这个单元格,当单元格重新加载时,它会采用这个缓存的版本。我只是猜测。是我的想法吗?我怎样才能改变这个不需要的 Action ?

解决方案

正如@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
}
}

最佳答案

从我在您的代码中看到的情况来看,您对 TableView 有很多误解。

我会试着更礼貌地说,但我做不到。 您在代码中引用 categoryCell 的方式是完全错误的! UITableviewCell 如果您将它们出队,则它们不是静态引用!

第一步:删除 categoryCell 变量!!!

表格 View 的工作方式如下:

cellForRowAtIndexPath 方法从 Storyboard或您的 Nib 中获取一个单元格,并一遍又一遍地重用该单元格!因此,一开始,您可能会按照自己的方式进行操作(创建对 categoryCell 的引用),但是一旦您的单元格多于屏幕上显示的单元格,情况就会发生变化,因为变量将引用不同的单元格!

Reading recommendation: 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 的新变量,它将反射(reflect)当前选择的类别...

在你的 Controller 中这样设置:

var selectedCategory : String?

当您重新加载一个部分或行或整个表格时,会发生什么情况,即再次调用给定行的所有 UITableViewDataSource 方法!在某种程度上, TableView 总是试图反射(reflect)模型的某些状态。

您应该始终通过重新加载行/部分或整个表格(取决于更改的内容)来反射(reflect)模型中的更改。

因此,当您选择类别时,您更改了模型并重新加载了您的行!

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)

}

呸!希望对您有所帮助...

关于ios - UITableView 在重新加载后重置 UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32553674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com