我已经创建了一个UITableView
并用我在API中获得的JSON数据填充它。我得到并正确放置但是当我滚动或删除一行时,一切都搞砸了!
标签和图像干扰;这是我的代码:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
var dict = productsArrayResult[indexPath.row]
let cellImage = UIImageView(frame: CGRect(x: 5, y: 5, width: view.frame.size.width / 3, height: 90))
cellImage.contentMode = .scaleAspectFit
let productMainImageString = dict["id"] as! Int
let url = "https://example.com/api/DigitalCatalog/v1/getImage?id=\(productMainImageString)&name=primary"
self.downloadImage(url, inView: cellImage)
cell.addSubview(cellImage)
let cellTitle = UILabel(frame: CGRect(x: view.frame.size.width / 3, y: 5, width: (view.frame.size.width / 3) * 1.9, height: 40))
cellTitle.textColor = UIColor.darkGray
cellTitle.textAlignment = .right
cellTitle.text = dict["title"] as? String
cellTitle.font = cellTitle.font.withSize(self.view.frame.height * self.relativeFontConstantT)
cell.addSubview(cellTitle)
let cellDescription = UILabel(frame: CGRect(x: view.frame.size.width / 3, y: 55, width: (view.frame.size.width / 3) * 1.9, height: 40))
cellDescription.textColor = UIColor.darkGray
cellDescription.textAlignment = .right
cellDescription.text = dict["description"] as? String
cellDescription.font = cellDescription.font.withSize(self.view.frame.height * self.relativeFontConstant)
cell.addSubview(cellDescription)
return cell
}
答案 0 :(得分:1)
您在重复使用可重复使用的单元格时多次添加子视图。你可以做的是在storyboard或xib文件中创建一个原型单元格,然后在cellForRowAtIndexPath中将该单元格出列。
您的单元格自定义类看起来与此类似,其中出口是从原型单元格中提取的。
注意:您需要为该原型单元分配可重用标识符。
class DemoProtoTypeCell: UITableViewCell {
@IBOutlet var titleLabel: UILabel!
@IBOutlet var descriptionLabel: UILabel!
@IBOutlet var titleImageView: UIImageView!
}
现在你可以deque DemoProtoTypeCell并相应地使用。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: DemoProtoTypeCell.self), for: indexPath) as! DemoProtoTypeCell
cell.titleImageView.image = UIImage(named: "demoImage")
cell.titleLabel.text = "demoTitle"
cell.descriptionLabel.text = "Your description will go here."
return cell
}
答案 1 :(得分:0)
那是因为您要添加子视图以供重复使用(以便它可能已经添加了以前添加的子视图)。
尝试检查单元格是否包含子视图并填写所需信息,如果没有子视图,则将其添加到单元格中。
选项1
if let imageView = cell.viewWithTag(1) {
imageView.image = //your image
} else {
let imageView = UIImageView(//with your settings)
imageView.tag = 1
cell.addSubview(imageView)
}
选项2
Crete UITableViewCell
子类已经拥有您需要的所有子视图。
答案 2 :(得分:0)
我使用了以下方法从单元格中删除所有子视图:
override func prepareForReuse() {
for views in self.subviews {
views.removeFromSuperview()
}
}
但是我创建了UITableViewCell
子类并在其中声明了这个方法。
你也可以像@sCha所建议的那样做一件事。将标记添加到子视图,然后使用相同的方法从单元格中删除子视图:
override func prepareForReuse() {
for view in self.subviews {
if view.tag == 1 {
view.removeFromSuperview()
}
}
}
希望这有帮助。
答案 3 :(得分:0)
我认为其他答案已经提到了一个解决方案。您应该子类化tableview单元格,只需更改每行的布局元素的值。
但我想解释一下为什么会出现这种奇怪的行为。
打电话的时候
tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
它尝试使用传递的标识符@"cell"
重用已创建的单元格。这样可以节省内存并优化性能。如果不可能,它会创建一个新的。
所以现在我们已经有了一个布局元素的单元格,并且已经填充了您的数据。然后,您的代码会在旧代码之上添加新元素。这就是为什么你的布局搞砸了。它只显示你是否滚动,因为第一个单元格没有先前的单元格加载。
当您对单元格进行子类化时,尝试在首次初始化时仅创建一次布局。现在,您可以将所有值传递给相应的布局元素,并让tableview完成它的工作。
答案 4 :(得分:0)
试试这个:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil
{
cell = UITableViewCell.init(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
}
for subView in cell.subviews
{
subView.removeFromSuperview()
}
// Your Code here
return cell
}