swift - 当我滚动 TableView 或 Collection View 时,为什么 Collection View 单元格中的数据会发生变化?

标签 swift

我正在尝试将 Collection View 嵌入 TableView 中。加载页面后,我将从数据库中逐字段检索数据,并在每次从数据库检索单个字段时重新加载数据。在这里,在重新加载 TableView 时,我需要检查该值,即“oneimage”,因此如果该值不为空,则应将其设置为 Collection View 单元格。问题是每当我滚动 TableView 时, Collection View 单元格中的数据就会交换。下面是代码

import UIKit
import Firebase
import FirebaseFirestore
import FirebaseAuth
import SDWebImage

struct values {
 var quesvalue: String
 var answvalue: String
 var ImageUrl = [String]()
}


class QuestionsCell: UITableViewCell,UICollectionViewDelegate {

 @IBOutlet weak var collectionview: UICollectionView!
 @IBOutlet weak var card: UIView!
 @IBOutlet weak var question: UILabel!
 @IBOutlet weak var answer: UILabel!
 @IBOutlet weak var speakbutton: UIButton!
 @IBOutlet weak var collectionviewh: NSLayoutConstraint!
 var imageArray = [String] ()
 override func awakeFromNib() {
    super.awakeFromNib()
 }
 override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

 }
}

extension QuestionsCell {
 func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & 
  UICollectionViewDelegate>(dataSourceDelegate: D, forRow row: Int) {
    collectionview.delegate = dataSourceDelegate
    collectionview.dataSource = dataSourceDelegate
    print("collectionviee.tag",collectionview.tag,row)
    collectionview.tag = row
    collectionview.contentOffset = .zero // Stops collection view if it was scrolling.
 }
}
class CollectionViewCell: UICollectionViewCell{

 @IBOutlet weak var backcard: UIView!
 @IBOutlet weak var imageview: UIImageView!
 var task: URLSessionDataTask?
 override func awakeFromNib() {
    super.awakeFromNib()

 }
 override func prepareForReuse(){
    imageview.image = nil
 }
}
class ViewController: UIViewController ,UITableViewDelegate, 
UITableViewDataSource,UICollectionViewDataSource,UICollectionViewDelegate {
@IBOutlet weak var tableview: UITableView!
var JSONArray = [String:Any]()
var quesArray = [String]()
var ansArray = [String]()
var answer : String!
var imagesarray = [String]()
var open : [values] = []
var oneimage = [String]()
var storedOffsets = [Int: CGFloat]()
override func viewDidLoad() {
    super.viewDidLoad()

    tableview.dataSource = self
    tableview.delegate = self

    tableview.rowHeight=UITableView.automaticDimension
    tableview.estimatedRowHeight=150
    Firestore.firestore().collection("User").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Popop").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Answers").document("Earlyyears").getDocument() { (document, error) in
                        if let document = document, document.exists {
                            self.open.removeAll()
                            self.imagesarray.removeAll()
                            self.oneimage.removeAll()
                            if let b1 = document.data()!["Name"] as? [String: Any] {
                                print("1",b1)
                                if let firstName = b1["Answer"] as? String {
                                    print("firstName is",firstName)

                                    if firstName != "No answer recorded"{
                                        self.answer = firstName
                                        self.ansArray.append(firstName)
                                        if let imageurlarray = b1["ImageURL"] as? [String] {
                                            self.imagesarray = imageurlarray
                                            print("imageurl array in meaning feild is",imageurlarray)
                                            self.open.insert(values(quesvalue: self.quesArray[0],answvalue: self.answer,ImageUrl: self.imagesarray), at: 0)
                                            self.tableview.reloadData()
                                        }


                                     }
                                }


                            }
                            if let b2 = document.data()!["Meaning"] as? [String: Any] {
                                print("1")
                                if let firstName = b2["Answer"] as? String {
                                    print("firstName is",firstName)

                                    if firstName != "No answer recorded"{
                                        self.answer = firstName
                                        self.ansArray.append(firstName)
                                        if let imageurlarray = b2["ImageURL"] as? [String] {
                                            self.imagesarray = imageurlarray
                                            print("imageurl array in meaning feild is",imageurlarray)
                                            self.open.insert(values(quesvalue: self.quesArray[1],answvalue: self.answer,ImageUrl: self.imagesarray), at: 1)
                                            self.tableview.reloadData()
                                        }


                                    }

                                }

                            }


                        } else {
                                print("Document does not exist")
                            }
                        }

}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("ansArry.count is",open.count)
    return open.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    print("entered into cellfor row at")
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! QuestionsCell
    print("quesrray,ansArray are",quesArray,ansArray,open)
    if open.count > indexPath.row{

        cell.question.text = open[indexPath.row].quesvalue
        cell.answer.text = open[indexPath.row].answvalue
        print("cell.ques.text",cell.question.text)


        oneimage = open[indexPath.row].ImageUrl
        print("onimage before checking",oneimage)
        if !oneimage.isEmpty{
            print("entered into oneimage not empty",oneimage)
            cell.collectionview.isHidden = false
            cell.collectionviewh.constant  = 160

   cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)


        }
        else{
            print("dont show collection view")
            cell.collectionview.isHidden = true
            cell.collectionviewh.constant  = 0
        }

    }
    else{
        print("<")
    }

    return cell
}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    print("imagesarray.count is",oneimage.count)

        print("oneimage.count")
        return oneimage.count


}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell: CollectionViewCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as? CollectionViewCell)!

  if oneimage.count > indexPath.row{
        if oneimage != [""] {
            let image = oneimage[indexPath.row]
            print("oneimage is",image)
            print("entered into oneimage not empty")
            cell.imageview.sd_setImage(with: URL(string: image))
         }
       }

    return cell

}

这是我的输出的屏幕截图。

The following image is visible when the page gets loaded The following page is visible when I scroll the collection view or table view

最佳答案

正如我在评论中提到的,这是因为可重用性。这意味着当一个单元格从底部/顶部出去时,相同的单元格(包含之前的设置)从顶部/底部进入。因此,如果您设置了异步内容,例如其上的远程图像,则它可能在错误的单元格上可见。当您要在单元格上设置图像时,您应该确保选择正确的单元格。

例如,您应该更改此:

cell.imageview.sd_setImage(with: URL(string: image))

像这样:

(collectionView.cellForItem(at: indexPath) as? CollectionViewCell)?.imageview.sd_setImage(with: URL(string: image))

这将向collectionView询问真实的单元格,而不是重用的单元格。我不知道 sd 库是如何工作的,但您可能想在库的 completionHandler 中执行此操作。

也许this article可以帮助你。

关于swift - 当我滚动 TableView 或 Collection View 时,为什么 Collection View 单元格中的数据会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59243617/

相关文章:

swift - 如何在 Xcode 中关闭颜色文字?

swift - 在 Swift 中比较字符串对象

swift - 在 swift 中使用 stride 的优势

ios - 如果 TableView 没有结果显示 "no results"标签(2 个计数)

ios - 从 JSON 图像 url swift 填充 collectionView

swift - 如何使用 SKAction 改变 SKSpriteNode 的位置

ios - 如何快速将 timeIntervalSinceNow 转换为可读日期

swift - Swift 4 中使用 MVVM 绑定(bind)不会触发 ViewController 中的事件

swift - 在 Swift 中 didFinishPickingMediaWithInfo 之前如何知道在 photoLibrary 中选择的媒体类型?

ios - 使用自动布局缩放垂直堆叠的按钮