【问题标题】:UITableViewCell + SDWebImage not showing/ persisting images on scrollUITableViewCell + SDWebImage 在滚动时不显示/保留图像
【发布时间】:2017-05-02 03:38:55
【问题描述】:

我有一个UITableView,带有一个表格源和一个自定义单元格。自定义单元格由一个 UIImageView 和两个标签组成。 UIImageView 图像必须从需要身份验证令牌才能下载的 url 下载。

我为此使用SDWebImage。在我必须在单个ImageView 中加载图像之前,我已经成功使用了该库。这是我第一次在TableView 中使用它,但我无法让它工作。这是我尝试过的东西

UITableViewSource.cs

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    var cell = peopleHomeController.tablePeopleSearch.DequeueReusableCell("PeopleNewSearchCell") as PeopleNewSearchCell ?? PeopleNewSearchCell.Create(); ;

    if(peopleHomeController.isSearch)
    {
        var data = peopleHomeController.peopleList.ElementAt(indexPath.Row);
        cell.UpdateCell(data);
    }
    else
    {
        var data = peopleHomeController.relatedPeopleList.ElementAt(indexPath.Row);
        cell.UpdateCell(data);
    }
    return cell;
}

PeopleNewSearchCell.cs

public  void UpdateCell(CustomValue mValue)
{
    labelPeopleEmail.Text = email = mValue.mail;
    labelPersonName.Text = mValue.name;

    if (!string.IsNullOrEmpty(mValue.mobilePhone))
    {
        labelPhone.Text = mValue.mobilePhone;
    }
    else
    {
        labelPhone.Text = "-";
    }


    var mUrl = "someimageurl";

    var manager = SDWebImageManager.SharedManager;
    manager.ImageCache.MaxCacheAge = 86400;
    manager.ImageCache.ShouldCacheImagesInMemory = true;
    SDWebImageDownloader mDownloader = manager.ImageDownloader;


    mDownloader.SetHttpHeaderValue(authToken, "Authorization");
    mDownloader.SetHttpHeaderValue("application/json; odata=verbose", "Accept");
    mDownloader.SetHttpHeaderValue("f", "X-FORMS_BASED_AUTH_ACCEPTED");


    try
    {
        mDownloader.DownloadImage(
         url: new NSUrl(mUrl),
         options: SDWebImageDownloaderOptions.UseNSUrlCache,
         progressBlock: (receivedSize, expectedSize) =>
         {
              //Track progress...
         },
         completedBlock: (image, data, error, finished) =>
         {

             if (image != null && finished)
             {
                 InvokeOnMainThread(() =>
                 {

                     this.imgPeopleProfile.Image = image;
                 });

             }
             if (error != null)
             {
                 InvokeOnMainThread(() =>
                 {
                     this.imgPeopleProfile.Image = UIImage.FromFile("ic_account.png");

                 });
             }
         }


        );
    }
    catch (Exception ex)
    {
    }


    CALayer profileImageCircle = imgPeopleProfile.Layer;
    profileImageCircle.CornerRadius = 40;
    profileImageCircle.BorderWidth = 2;
    profileImageCircle.BorderColor = UIColor.White.CGColor;
    profileImageCircle.MasksToBounds = true;
}

public override void PrepareForReuse()
{
    base.PrepareForReuse();
    imgPeopleProfile.CancelCurrentImageLoad();
    imgPeopleProfile.Image = null;
}  

使用上面的代码,图像已下载但未显示,但在滚动时显示错误的单元格。此外,当图像显示在错误的单元格上时,如果我不滚动,错误单元格的图像也会消失。 (我希望我说得通)。正如一些关于 SO 的答案中提到的,我还取消了 PrepareForReuse() 上的任何图像加载。

2 天以来,我完全被这个问题困扰,非常感谢任何帮助。

【问题讨论】:

  • 这一行 var cell = peopleHomeController.tablePeopleSearch.DequeueReusableCell("PeopleNewSearchCell") as PeopleNewSearchCell 是什么? PeopleNewSearchCell.Create(); ; ? 为什么要创建单元格?
  • @KKRocks 我已经创建了一个带有 xib 的自定义单元格,所以我正在考虑一个逻辑,如果该单元格不存在,则创建一个
  • 表格视图重用单元格来显示数据列表。当您下载图像时,它不会与预期的单元格绑定。这就是图像在单元格中错位的原因。
  • 那么你需要检查那里的条件如果单元格不存在然后创建单元格。您现有的代码每次都会创建单元格。
  • @JitendraSolanki 感谢您的回复。你能建议一个解决方法吗?

标签: ios uitableview xamarin.ios uiimageview sdwebimage


【解决方案1】:

使用此行创建一个单元格,如果找到,它将使用现有单元格,否则将为您创建一个新单元格。

let cell = tableView.dequeueReusableCell(withIdentifier: "PeopleNewSearchCell", for: indexPath)as! PeopleNewSearchCell

现在在所有方法之外声明mDownloader,因为它可以在您的所有方法中访问,例如 iVar:

var mDownloader:SDWebImageDownloader!

然后在您的viewDidLoad() 方法中为SDWebImage 设置令牌和其他字段

var manager = SDWebImageManager.SharedManager;
manager.ImageCache.MaxCacheAge = 86400;
manager.ImageCache.ShouldCacheImagesInMemory = true;

mDownloader = manager.ImageDownloader;


mDownloader.SetHttpHeaderValue(authToken, "Authorization");
mDownloader.SetHttpHeaderValue("application/json; odata=verbose", "Accept");
mDownloader.SetHttpHeaderValue("f", "X-FORMS_BASED_AUTH_ACCEPTED");

现在在 tableView 的数据源方法中使用mDownloader 为单元格下载图像:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
  let cell = tableView.dequeueReusableCell(withIdentifier:   "PeopleNewSearchCell", for: indexPath)as! PeopleNewSearchCell

  if(peopleHomeController.isSearch)
  {
      var data = peopleHomeController.peopleList.ElementAt(indexPath.Row);
    cell.UpdateCell(data);
  }else{
     var data = peopleHomeController.relatedPeopleList.ElementAt(indexPath.Row);
    cell.UpdateCell(data);
  }

 //download an image
 try
   {
    mDownloader.DownloadImage(
     url: new NSUrl(mUrl),
     options: SDWebImageDownloaderOptions.UseNSUrlCache,
     progressBlock: (receivedSize, expectedSize) =>
     {
          //Track progress...
     },
     completedBlock: (image, data, error, finished) =>
     {

         if (image != null && finished)
         {
             InvokeOnMainThread(() =>
             {

                 cell.imgPeopleProfile.Image = image;
             });

         }
         if (error != null)
         {
             InvokeOnMainThread(() =>
             {
                 cell.imgPeopleProfile.Image =  UIImage.FromFile("ic_account.png");

             });
         }
     }


    );
}
catch (Exception ex)
{
}
return cell;
}

并从updateCell() 方法中删除图片下载代码。

【讨论】:

  • 感谢您的回复。但我改变了这个,它仍然是相同的场景
  • 我无法从我的 GetCell() 访问 imgPeopleProfile,因为它位于自定义单元类中
  • 自定义单元类中没有imgPeopleProfile的出口吗?为了将值分配给单元格的视图,指定的视图应该可以从表格视图的数据源访问单元格。所以让它工作,让 imgPeopleProfile 视图在单元格中可访问。为了使其可访问,您可以从 xib 创建一个出口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多