我的程序中有一个带有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]!
谢谢!
答案 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开头