2017-06-16 75 views
0

我在我的UITableView中出现了可重复使用的细胞功能出现了一些问题。 tableview有几个单元格,每个单元格都包含一个按钮。由于细胞再利用导致的重叠按钮

当我滚动时,单元格被重新创建,并且新按钮开始重叠旧按钮(直到我在同一个单元格中有一堆相同的按钮)。我听说你应该使用removeFromSuperview函数来解决这个问题,但我不确定如何去做。

这里是我的应用程序的图片:

image

这里是cellForRowAtIndexPath(其中问题发生)

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) 


    let nameLabel: UILabel = { 
     let label = UILabel() 
     label.text = "Sample Item" 
     label.translatesAutoresizingMaskIntoConstraints = false 
     return label 
    }() 

    let actionButton = YSSegmentedControl(
     frame: CGRect.zero, 
     titles: [ 
      "No", 
      "Yes" 
     ]) 
+0

您还没有发布'cellForRowAtIndexPath'的整个函数。你需要发布更多的功能。特别是,您将标签和按钮/分段控件添加到单元格的位。我怀疑你每次出队时都会添加这些项目,而不会删除它们。你的形象是否真的说明了这个问题?我看不到图像中的任何重叠按钮。 –

+0

不建议在'cellForRowAt indexPath.'中创建或删除视图。 – Maddy

回答

0

你看到多个按钮的出现是因为原因每次需要新的表格单元格时,都会调用cellForRowAtIndexPath:方法。由于您可能在该方法体中创建按钮,因此每次单元格被重用时都会重新创建该按钮,并且您会看到它们堆叠在顶部。使用dequeueReusableCell的正确方法是:使用自定义元素创建UITableViewCell的子类并将其设置为故事板中表格单元格的类。然后当你调用dequeueReusableCell时:你会得到一个你的子类的副本,它将包含你所有的自定义代码。你需要做一个类型转换得到任何的是自定义代码这样的访问:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
    if let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as? MyCustomCellClass { 
    cell.nameLabel.text = "Sample item" 
    } 

    // This return path should never get hit and is here only as a typecast failure fallback 
    return tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath); 
} 

您的自定义单元格的子类会再看看这样的事情:

class MyCustomCellClass: UITableViewCell { 
    @IBOutlet var nameLabel: UILabel! 
    @IBOutlet var actionButton: UIButton! 

    @IBAction func actionButtonPressed(_ sender: UIButton) { 
    //Do something when this action button is pressed 
    } 
} 
+0

换句话说,*永远不会*添加或删除'cellForRowAt'中的子视图。相反,将它们添加到别处(*咳嗽*故事板*咳嗽*),并在'cellForRowAt'中更改它们的*属性*。 – NRitH

+0

我会,但我不使用故事板。我尝试过使用自定义单元类,但它显得更加困难。 –

+0

@NicholasTiwari如果我的记忆正确地为我服务(这已经有一段时间了),但是如果你不想使用完整的故事板,你应该只能使用普通的nib文件。否则,自定义单元类是要走的路。如果您正在为此苦苦挣扎,请发布问题以便我们提供帮助。 – JiuJitsuCoder

0

您可以添加新标签/按钮cellForRowAtIndexPath,但在创建并添加新标签之前,您需要确保没有现有的标签/按钮。一种方法是将标签设置为标签/按钮,并且在生成新标签/按钮之前,检查包含标签的视图是否已经在单元格中。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 

    if let label = cell.viewWithTag(111) as? UILabel 
    { 
     label.text = "Second Labels" 
    } 
    else{ 
     let label = UILabel() 
     label.tag = 111 
     label.text = "First Labels" 
     cell.addSubview(label) 
     label.translatesAutoresizingMaskIntoConstraints = false 
     label.frame = CGRect(x:0, y:10, width: 100, height:30) 
    } 

    return cell 
}