2017-09-19 5 views
0

UITableViewを作成し、JSONデータで埋めました。私のAPIの中に入れました。私はすべてを正しく取得して配置しますが、行をスクロールまたは削除するとすべてがうんざりになります!JSONデータをUITableViewに正しく表示する

Take a look at the screenshot

ラベルとイメージ妨害します。あなたは、細胞(それはすでに以前に追加されたサブビューを持つことができるように)再利用にサブビューを追加しているためだ

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

あなたはすべて間違ってやっている、あなたはのUITableViewCellのサブクラス化のために別々のクラスを作成し、そこにすべてのコントロールを追加する必要があり、細胞を作成するためのこの方法は、 –

+0

@Winnストーン正しくありません:ザッツセル理由再利用され、余分な時間を費やしてラベルや画像を追加します –

答えて

1

再利用可能なセルのデキュー中にサブビューを複数回追加しています。あなたができることは、ストーリーボードまたはxibファイルのいずれかでプロトタイプセルを作成し、そのセルをcellForRowAtIndexPathでデキューします。

Design Prototype cell and assgin with the custom class

セルのカスタムクラスは、出口は、プロトタイプセルから引き出される場合、このようになります。

注:プロトタイプセルにReusable Identifierを割り当てる必要があります。

class DemoProtoTypeCell: UITableViewCell { @IBOutlet var titleLabel: UILabel! @IBOutlet var descriptionLabel: UILabel! @IBOutlet var titleImageView: UIImageView! }

今、あなたは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 
} 
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

クレタすでにあなたが必要とするすべてのサブビューを持つUITableViewCellサブクラス。私は、セルからすべてのサブビューを削除する方法以下で使用している

0

override func prepareForReuse() { 
    for views in self.subviews { 
     views.removeFromSuperview() 
    } 
} 

しかし、私はUITableViewCellサブクラスを作成し、その中にこのメソッドを宣言しました。

@sChaが示唆しているように、あなたは1つのことを行うこともできます。サブビューにタグを追加し、同じ方法を使用してセルからサブビューを削除します。

override func prepareForReuse() { 
    for view in self.subviews { 
     if view.tag == 1 { 
      view.removeFromSuperview() 
     } 
    } 
} 

これが役に立ちます。

0

私はすでに解決策について言及していると思います。 tableviewセルをサブクラス化し、各行のレイアウト要素の値を変更するだけです。

しかし、私はあなたがなぜこの奇妙な動作をするのか説明したいと思います。

あなたは tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 呼び出すとき、それは渡された識別子@"cell"ですでに作成されたセルを再利用しようとします。これにより、メモリが節約され、パフォーマンスが最適化されます。可能でない場合は、新しいものを作成します。

これで、既にレイアウト要素が設定されたセルが取得され、データが入力されました。あなたのコードは古い要素の上に新しい要素を追加します。それはあなたのレイアウトが台無しにされている理由です。最初のセルには前のセルがロードされていないため、スクロールすると表示されます。

セルをサブクラス化するときは、最初の初期化時にレイアウトを1回作成するようにしてください。これで、すべての値をそれぞれのレイアウト要素に渡して、テーブルビューにそのことをさせることができます。

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 
    } 
関連する問題