0
votes

I have Xamarin.iOS project, where is I use TableView

Here is tableView source code

 public class ExperienceSourceNew: UITableViewSource
{
    private UINavigationController primNav { get; set; }
    private UITableView tableView { get; set; }
    List<Experience> TableItems;
    ExperienceViewControllerNew _owner;
    static NSString cellIdentifier = new NSString("newcell_id");
    public ExperienceSourceNew(List<Experience> items, ExperienceViewControllerNew owner, UINavigationController nav)
    {
        TableItems = items;
        _owner = owner;
        primNav = nav;
    }
    public override nint RowsInSection(UITableView tableview, nint section)
    {

        if (TableItems.Count == 0)
        {


            var noDataLabel = new UILabel
            {
                Text = "No Experiences at your location at this time. Try to change destination",
                TextColor = UIColor.Black,
                TextAlignment = UITextAlignment.Center,
                LineBreakMode = UILineBreakMode.WordWrap,
                Lines = 0
            };
            tableview.BackgroundView = noDataLabel;
            tableview.SeparatorStyle = UITableViewCellSeparatorStyle.None;

            return TableItems.Count;
        }
        else
        {
            tableview.BackgroundView = null;
            tableview.SeparatorStyle = UITableViewCellSeparatorStyle.SingleLine;
            return TableItems.Count;
        }


    }

    public override async void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        var selectedExperience = await ExperienceMethods.GetSelectedTour(TableItems[indexPath.Row].id);
        if (selectedExperience == "Saved")
        {
            ExperienceDetailViewController ExperienceDetailController = primNav.Storyboard.InstantiateViewController("ExperienceDetailViewController") as ExperienceDetailViewController;
            primNav.PushViewController(ExperienceDetailController, true);

        }
        else
        {
            UIAlertController okAlertController = UIAlertController.Create("", "Cannot select this experience", UIAlertControllerStyle.Alert);
            okAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
        }
        tableView.DeselectRow(indexPath, true);

    }


    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        var cell = (ExperienceCellNew)tableView.DequeueReusableCell(cellIdentifier, indexPath);
        Experience item = TableItems[indexPath.Row];
        cell.UpdateCell(item);
        return cell;
    }

I use custom Cell for TableView, so here is code for it

public ExperienceCellNew (IntPtr handle) : base (handle)
    {

    }
    internal void UpdateCell(Experience experience)
    {
        var image_url = "https://xplorpal.com/" + experience.cover_image.img_path + "/150x150/" + experience.cover_image.img_file;
        ExperienceTitleNew.Text = experience.title;
        ExperiencePriceNew.Text = "$" + experience.price;
        NSUrlSession session = NSUrlSession.SharedSession;
        var dataTask = session.CreateDataTask(new NSUrlRequest(new NSUrl(image_url)), (data, response, error) =>
        {
            if (response != null)
            {
                DispatchQueue.MainQueue.DispatchAsync(() =>
                {
                    ExperienceImageNew.Image = UIImage.LoadFromData(data);
                });
            }
        });

        dataTask.Resume();
    }
}

My problem, that images not appears on View load, I have text in labels, but don't have images. If I scroll TableView, images are appears in cells.

Where can be problem and how to solve it?

2

2 Answers

2
votes

Table Views with large number of rows display only a small fraction of their total items at a given time.It's efficient for table views to ask for only the cells for row that are being displayed Therefor on scrolling the table view, the cells get re-used and the data within the cell is repopulated.

Since you are using a downloaded image it appears to be slow.

You can try loading the image of the exact size as the image view within the cell.

This is similar to your issue

And also assigning the image to imageview on main thread and make it synchronous as UI changes require synchronous access to main thread.

0
votes

As an alternative, you can use FFImageLoading which will let you do this

ImageService.LoadUrl(image_url).Into(ExperienceImageNew);