【问题标题】:How to prevent UITableView from reuse custom cells Swift如何防止 UITableView 重用自定义单元格 Swift
【发布时间】:2016-06-21 08:05:35
【问题描述】:

在我的应用中,我使用 UITableViewcustom 单元格。

对于每个单元格,我实现了创建它的函数,并在 cellForRow 中调用这些函数。

这是来自项目的代码示例:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


    if indexPath.row == CellsTypes.profileImageCell.rawValue {

        return createIntroCell()
    }

    else if indexPath.row == CellsTypes.fullNameCell.rawValue {

        return createUserNameCell()

    }

    else if indexPath.row == CellsTypes.emailCell.rawValue {

        return createEmailCell()


    }
    else  {

        return createPasswordCell()

    }}

这些是创建函数:

func createUserNameCell() -> TextFieldTableViewCell {

    let fullNameCell = self.tableView.dequeueReusableCellWithIdentifier("text-field-cell") as! TextFieldTableViewCell
    fullNameCell.awamirTextFieldNib.setNormalTextFieldCellContent("Full Name")
    fullNameCell.awamirTextFieldNib.textFieldContent.tag = CellsTypes.fullNameCell.rawValue
    fullNameCell.awamirTextFieldNib.textFieldContent.returnKeyType = .Next
    fullNameCell.awamirTextFieldNib.textFieldContent.delegate = self
    return fullNameCell
}

func createEmailCell() -> TextFieldTableViewCell {

    let emailCell = self.tableView.dequeueReusableCellWithIdentifier("text-field-cell") as! TextFieldTableViewCell
    emailCell.awamirTextFieldNib.setNormalTextFieldCellContent("Email")
    emailCell.awamirTextFieldNib.textFieldContent.tag = CellsTypes.emailCell.rawValue
    emailCell.awamirTextFieldNib.textFieldContent.returnKeyType = .Next
    emailCell.awamirTextFieldNib.textFieldContent.delegate = self
    return emailCell
}
 func createPasswordCell() -> TextFieldTableViewCell {

    let textFieldCell = self.tableView.dequeueReusableCellWithIdentifier("text-field-cell") as! TextFieldTableViewCell
    textFieldCell.awamirTextFieldNib.setPasswordCellContent("Password")
    textFieldCell.awamirTextFieldNib.textFieldContent.tag = CellsTypes.passwordCell.rawValue
    textFieldCell.awamirTextFieldNib.textFieldContent.returnKeyType = .Next
    textFieldCell.awamirTextFieldNib.textFieldContent.delegate = self

    return textFieldCell
}

问题是如果我重新加载表格视图,单元格的内容会因为单元格的可重用性而改变。即:重新加载tableview后,第一个单元格的内容变成了第二个单元格,第二个单元格的内容变成了第一个单元格!!

如何防止 tableview 重复使用单元格?!

谢谢。

【问题讨论】:

  • 你不应该阻止这一点,你应该高兴UITableView有这个能力=)
  • 你不应该阻止细胞重复使用......相反,你应该学会重复使用你的细胞,否则你会做很多不必要的处理并使你的应用程序电池效率低下
  • 你的代码对我来说看起来有点乱,你确实重用了单元格,但在将重用单元格的内容设置为 normal 之前,你如何重置重用单元格的内容并不明显pawwsord 等...

标签: ios swift uitableview


【解决方案1】:

尝试为每种单元格类型使用不同的标识符,因此不要为每个单元格使用"text-field-cell",创建一个“全名”、“密码”等。不确定您将如何创建单元格,但如果您正在使用 registerNib 或 registerClass,您需要为每个不同的标识符注册它

self.tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "full name")
self.tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "password")
self.tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "email")

【讨论】:

  • 旁注,您的单元格似乎只是固定在它们的位置上,您可以只使用情节提要中的静态表格视图,而不必实现所有这些东西。但也许不是
  • 嘿,谢谢 :) 请检查我在上一个答案中的评论吗?它也是关于你的答案:)
  • 您不应该将标识符设置为 nil,请查看我的更新答案以了解我的意思
  • 将每个标识符视为一个单元格池,这些单元格仅被该标识符重用,因此如果在cellForRowAtIndexPath 中将特定标识符出列,则只有来自该标识符池的单元格将被重用。所以“全名”单元格永远不会被“密码”单元格等重用
  • 但通常如果每个单元格使用相同的类,通常的方法是重置单元格中的所有字段,然后填充所需的数据,而不是使用许多不同的单元格标识符看起来基本相同的细胞
【解决方案2】:

尝试在您的自定义单元格中实现prepareForReuse 方法并将所有字段文本设置为零。

override func prepareForReuse() -> Void {
   awamirTextFieldNib.text = nil
}

希望有帮助

【讨论】:

  • 谢谢,但是这样我会丢失用户在重新加载 tableView 之前输入的 UItextfield 的文本:(
  • 您可以将此文本存储在 nsarray 中并通过您的 indexPath 取回
【解决方案3】:

不要使用默认的 UITableView 并反对单元格的重用,它确实嵌入在它的行为中。

尝试调整您的代码,使其能够很好地重复使用单元格,或者如果这真的不可能,我猜您必须编写自己的自定义表格视图(但我根本不建议这样做)

【讨论】:

    【解决方案4】:

    您不应该阻止这种情况,但如果您真的想这样做,我认为不将单元格标识符设置为您的 UITableViewCell 应该可以解决问题。当您调用dequeueReusableCellWithIdentifier 时,它会找不到任何单元格并会创建一个新单元格。但同样,不建议这样做,因为 UITableView 被用于具有重用能力。

    此外,正如@Fonix 所建议的那样,为UITableView 的每个单元格使用不同的单元格标识符可能会在继续使用单元格重用系统的同时解决您的问题。

    编辑: 当您谈论丢失 UITextField 中的文本内容时,可能要做的唯一更改是将您的 @propery weak 属性更改为 strong

    希望这会有所帮助。

    【讨论】:

    • 非常感谢。但是如何使您的答案起作用?你能解释更多吗?我从xib中删除了identifire。但是当注册 nib 时,你应该传递一个 identifire :S 并将其设置为 nil,并且在 cellforrow 中也会出现同样的问题。
    • 您可以在注册 nib 时传递一个标识符,比如说 'abc' 并在重用时使用另一个标识符,例如 'cba'。但是你会失去效率......
    猜你喜欢
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多