在UITable View Swift中滚动时图片混合

时间:2018-07-16 18:57:46

标签: ios swift uitableview scroll uiimage

我的程序中有一个带有dequeueReusableCells的UITable视图 我应该从服务器加载几张图像并以幻灯片形式显示它们

我有一个自定义单元格,在配置每个单元格时,我分别在DispatchQueue.global(qos:.userInitiated).async和DispatchQueue.main.async中下载图像,将下载的图片添加到幻灯片图像

但是当我开始滚动一些不应该有图片的单元格时,请重复另一个单元格的图片

你知道是什么原因造成的吗?!

我正在使用swift以及ImageSlideShow pod在每个单元格中进行幻灯片放映

这是我的代码的某些部分:

在新闻单元课程中,我有以下部分用于获取图像:

[svc.jenkins@node6 ~]$ kubelet --version
Kubernetes v1.10.4

这是cellForRow方法:

class NewsCell: UITableViewCell{

    @IBOutlet weak var Images: ImageSlideshow!
    @IBOutlet weak var SubjectLbl: UILabel!
    @IBOutlet weak var NewsBodyLbl: UILabel!

    func configureCell(news: OneNews) {


        self.SubjectLbl.text = news.Subject
        self.NewsBodyLbl.text =  news.Content



        if news.ImagesId.count==0{
            self.Images.setImageInputs([ImageSource(image: UIImage(named: "ImagePlaceholderIcon")!)])
        } 
        else{
            for imgId in news.ImagesId {

                let Url = URL(string: "\(BASE_URL)\(NEWS_PATH)/\(imgId)/pictures")
                DispatchQueue.global(qos: .userInitiated).async {

                    let data = try? Data(contentsOf: Url!)

                    DispatchQueue.main.async {

                        if let d = data {
                            let img = UIImage(data: data!)!
                            imageSrc.append(ImageSource(image: img))
                            self.Images.setImageInputs(imageSrc);
                        }
                    }
                }
            }

        }
    self.Images.slideshowInterval = 3

}

getGeneralNews()是一个返回一系列新闻的吸气剂 所以我在cellForRowAt中所做的就是在指定的索引路径中获取新闻并用它配置我的单元。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = generalNewsTableView.dequeueReusableCell(withIdentifier: "NewsCell" , for: indexPath) as!  NewsCell

    if let news = NewsInfo.sharedInstance.getGeneralNews(){
        cell.configureCell(news: news[indexPath.row])

    }
    return cell

}

每个新闻都包含一组图片ID

这些是我的OneNews类中的字段         var Subject:字符串!         var内容:字符串!         var ImagesId:[Int]!

谢谢!

3 个答案:

答案 0 :(得分:2)

UITableViewCell在滚动时会被重用。当一个单元格离开屏幕顶部时,它将被重新使用以显示在屏幕底部的另一行。

UITableViewCell具有您可以覆盖的方法@Override protected String doInBackground(Integer... integers) { monCountTimer = new CountDownTimer(6000, 1000) { @Override public void onTick(long millisUntilFinished) { myDownloadTask.this.inc++; myDownloadTask.this.getMaProgressBar().setProgress((int) myDownloadTask.this.inc * 100 / (6000 / 1000)); } @Override public void onFinish() { } }; monCountTimer.start(); } 。您可以使用该方法清除iamgeViews或应重置的任何其他状态,或取消下载图像。

在您的情况下,您可能不应该使用prepareForReuse,因为它不能为您提供取消它的方法。 Data(contentsOf:)是一个更好的选择,因为它可以让您在请求完成之前取消它。

答案 1 :(得分:1)

您可以尝试类似的方法。该代码的主要思想是提供一个唯一的数字,以检查单元是否被重复使用。

  • 我已在代码中重命名了许多属性,因为非类型的大写标识符使代码难以阅读。您不能只替换原始SELECT * FROM companies a WHERE name_tokens @@ to_tsquery(replace('TIAA Access Small-Cap Blend Index Fund T1', ' ', ':* &')) 的整个定义。
  • 原始定义中没有NewsCell的声明。我认为这是一个局部变量。如果它是全局变量,则可能导致其他问题,您应该避免。

(标有imageSrc的重要行。)

###

请记住,图像的顺序可能与class NewsCell: UITableViewCell { @IBOutlet weak var images: ImageSlideshow! @IBOutlet weak var subjectLbl: UILabel! @IBOutlet weak var newsBodyLbl: UILabel! //### An instance property, which holds a unique value for each cellForRowAt call var uniqueNum: UInt32 = 0 func configureCell(news: OneNews) { self.subjectLbl.text = news.subject self.newsBodyLbl.text = news.content let refNum = arc4random() //### The output from `arc4random()` is very probably unique. self.uniqueNum = refNum //### Assign a unique number to check if this cell is reused if news.imagesId.count==0 { self.images.setImageInputs([ImageSource(image: UIImage(named: "ImagePlaceholderIcon")!)]) } else { var imageSrc: [ImageSource] = [] //### for imgId in news.imagesId { let Url = URL(string: "\(BASE_URL)\(NEWS_PATH)/\(imgId)/pictures") DispatchQueue.global(qos: .userInitiated).async { let data = try? Data(contentsOf: Url!) DispatchQueue.main.async { //### At this point `self` may be reused, so check its `uniqueNum` is the same as `refNum` if self.uniqueNum == refNum, let d = data { let img = UIImage(data: d)! imageSrc.append(ImageSource(image: img)) self.images.setImageInputs(imageSrc) } } } } } self.images.slideshowInterval = 3 } } imagesId的顺序不同(如Duncan C的评论所述)。

请尝试。

答案 2 :(得分:0)

如果您想尝试使用此小代码修复,而不必覆盖单元格的prepareForReuse,只需更改configure单元格即可:

if news.ImagesId.count==0{
    self.Images.setImageInputs([ImageSource(image: UIImage(named: "ImagePlaceholderIcon")!)])
} 
else{
// STUFF
}

self.Images.setImageInputs([ImageSource(image: UIImage(named: "ImagePlaceholderIcon")!)]) 

if news.ImagesId.count > 0{
// STUFF
}

因此,即使重复使用,每个单元格也会以placeholderIcon开头