Lydia
Lydia

Reputation: 2117

Custom tableview scrolling issue on cells

I have a programatically created tableview

var tableView: UITableView  =   UITableView()
var items = ["1","2","3","4","5","6"," 1","L 2","La 3","La 4","La 5","La 6","L 7","La 8","La 9","La 10","La 11","Lab 12","Lab 13","Lab 14","Lab 15","Lab 16","Lab 17","Lab 18","Lab 19","Lab 20","La 1","L 2","La 3"]

   override func viewDidLoad() {
    super.viewDidLoad()
    tableView.frame         = CGRectMake(0, 50, self.view.frame.width,100);  //If we give self.view.frame.height It worked because no need to scroll
    tableView.delegate      = self
    tableView.dataSource  =  self
    tableView.estimatedRowHeight = 30
   tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    self.view.addSubview(tableView)
    }

Here is the code which have problem

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
        if indexPath.row == 2 || indexPath.row == 3 {
            var redBtn = UIButton()
            redBtn = UIButton(frame: CGRectMake(0, 0, 40, 40))
            redBtn.backgroundColor = UIColor.redColor()
            redBtn.setTitle("das", forState: UIControlState.Normal)         
            cell.contentView.addSubview(redBtn)
        }else {
        cell.textLabel?.textAlignment = NSTextAlignment.Center
        cell.textLabel?.text = items[indexPath.row]
       }
       return cell
   }
}

In the 2 nd and 3 rd row only i need to display the button.But when scroll the tableview it displays in all the cells.If increase the tableview height to view height then no problem becuase there is no scrolling happend.

I read this question UITableView scrolling and redraw issue from this i found it is because of reuse cell issue while scrolling.But that solution did not work for me.

Suitable solutions are welcome.I gave full code so you can copy and paste it to the project, and get the problem.

THANKS iN ADVANCE

Upvotes: 3

Views: 4163

Answers (1)

Icaro
Icaro

Reputation: 14845

When you reuse cells the old values still persists on it so everytime you use dequeueReusableCellWithIdentifier you need to reset to the default values or the last values still cached in it. In your specific case you need to remove the buttons that you create from the cell or set it to hidden in your else statement.

From apple documentation:

The table view’s data source implementation of tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell.

The best way for you to implement this is to create a custom cell with all components as you need (button, label, etc) as you dequeue the new custom cells you turn the property hidden to true or false as you need.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! MyCustomCell
        if indexPath.row == 2 || indexPath.row == 3 {
            redBtn.hidden = false
            cell.contentView.addSubview(redBtn)
        }else {
            redBtn.hidden = true
            cell.textLabel?.textAlignment = NSTextAlignment.Center
            cell.textLabel?.text = items[indexPath.row]
      }
      return cell

It isn't a good idea to programmatically create a button on the fly in this case as you would have to loop all the subviews in the cell for each reusable cell to find out if it already exist to decide if you need to create or remove, like below:

for button:AnyObject in subviews{
    if(button .isKindOfClass(UIButton)){
       if(button.accessibilityIdentifier == "MyButton"){
            println("Button Already Exists")
        }else{
            println("Create new button")
        }
    }
}

I hope that helps you

Upvotes: 2

Related Questions