13

In my App I use UITableView with custom cells.

for each cell I implement function to create it, and call these functions in cellForRow.

this is an code example from project :

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()

    }}

and these are the creation functions :

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
}

the problem is if I reload the tableview the content of cells changed because of the reusablity of the cells. i.e: after reload the tableview the content of the first cell become in the second cell, and the content of the sencond on became in the first cell!!

how can I prevent tableview from reusable the cells?!

Thanks.

Rawan
  • 1,589
  • 4
  • 23
  • 47
  • 2
    You should not prevent from this, you should be happy that `UITableView` have this ability =) – Yury Jun 21 '16 at 08:07
  • you shouldnt prevent cell reuse... instead you should learn to reuse your cells otherwise you will be doing a lot of unnecessary processing and making your app battery inefficient – Fonix Jun 21 '16 at 08:07
  • you code looks a bit messy to me, you indeed reuse the cells but it is not obvious how you _reset_ the reused cell's content before you set it as _normal_, _pawwsord_, etc... – holex Jun 21 '16 at 08:15
  • Possible duplicate of [Disable cell reuse for small fixed-size UITableView](https://stackoverflow.com/questions/6443533/disable-cell-reuse-for-small-fixed-size-uitableview) – Gobe Jun 09 '19 at 21:00

4 Answers4

13

Try using a different identifier for each of the cell types, so dont use "text-field-cell" for each one, make one "full name", "password" etc. not sure how you are going about creating your cells, but if you are using the registerNib or registerClass, you will need to register it for each different identifier

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")
Fonix
  • 11,447
  • 3
  • 45
  • 74
  • side note, it seems like your cells are just fixed in their positions, you could just use a static tableview from the storyboard and you wouldnt have to implement all this stuff. but maybe not – Fonix Jun 21 '16 at 08:16
  • hey, thanks :) please can u check my comment in the previous answer? its about ur answer too :) – Rawan Jun 21 '16 at 08:26
  • you shouldnt set the identifier to nil, check my updated answer on what i mean – Fonix Jun 21 '16 at 08:31
  • think of each identifier as a pool of cells that get reused only for that identifier, so if in `cellForRowAtIndexPath` you dequeue a particular identifier, only cells from that identifiers pool will get reused. so a "full name" cell will never get reused for a "password" cell etc – Fonix Jun 21 '16 at 08:33
  • but usually if each cell is using the same class, the normal approach would be to just reset all the fields in the cell, then populate the data thats needed, instead of having lots of different cell identifiers for cells that looks basically the same – Fonix Jun 21 '16 at 08:35
  • Hey thanks.. I was trying to fix this issue for past 2 days. This actually solved my problem.. +1 for your answer.. – Swayambhu May 25 '17 at 13:04
11

Try to implement prepareForReuse method in your custom cell and set all fields text to nil.

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

Hope this help

iSashok
  • 2,326
  • 13
  • 21
  • thanks, but in this way I lose the text of the UItextfield which the user entered before reloading the tableView :( – Rawan Jun 21 '16 at 08:13
  • You can store this text in nsarray and get it back by your indexPath – iSashok Jun 21 '16 at 08:15
2

Don't use the default UITableView and fight the reuse of cells, it's really embedded in it's behaviour.

Try to adapt your code so it works well with reusing cells, or if that's really impossible, you'd have to write your own custom table view I guess (but I don't recommend that at all)

Pieter
  • 17,435
  • 8
  • 50
  • 89
1

You shouldn't prevent that, but if you really want to, I think that not setting cell identifier to your UITableViewCell should do the trick. When you'll call dequeueReusableCellWithIdentifier, it will find no cell and will create a new one. But again, it's not recommended as UITableView is made to be used with reuse ability.

Moreover, as @Fonix suggests, using a different cell identifier for each cell of your UITableView might solve your issue while keeping using cell reuse system.

Edit : As you're talking about losing text content in your UITextField, maybe the single change to make is changing your @propery weak attribute to strong.

Hope this helps.

AnthoPak
  • 4,191
  • 3
  • 23
  • 41
  • Thanks a lot. but how to make your answr worked? can u explain more please? I remove the identifire from the xib. but when register the nib u should pass an identifire :S and cnt set it as nil, and also in the cellforrow the same problem. – Rawan Jun 21 '16 at 08:24
  • You could pass an identifier when registering the nib, let's say 'abc' and use another one when reusing, as 'cba'. But you'll lose efficiency... – AnthoPak Jun 21 '16 at 08:27