Introduction

In this post you will see how to implement LazyLoading on your TableView. In my previous article, I explained how to manage the scrolling. It’s time to continue our journey with Xamarin IOS!

What is LazyLoading ?

The lazy loading is a design pattern. The idea is to load only what you need. The consequence is a better efficiency of your application. Because you reduce the amount of data and the time needed to load everything. (More information on wikipedia)

TableView LazyLoading

Model & Data

In this example, we will need a model. We will use a very simple one: a comment with only one field.

public class Comment
{
            public string Text { get; set; }
}
Code language: C# (cs)

Now we will add some fake data. Actually, we need enough data to reach the end of out TableView. It’s depends on the size of your cell of course.

public List<Comment> AllComments = new List<Comment>
{
	    new Comment { Text = "Who are you ?" },
	    new Comment { Text = "Im your father !" },
            new Comment { Text = "What ?" },
            new Comment { Text = "Hey boy" },
            new Comment { Text = "All your base are belong to us" },
            new Comment { Text = "Im your mother" },
};
Code language: C# (cs)

LazyLoading Implementation

Obviously we need a method to load our data. In this example, there are two parameters. The first one allows you to define the start index, and the second one the number of items we want to load each time we reach the end of the scrolling. (More information about the GetRange here)

public List<Comment> GetComments(int offset, int itemPerPage)
        {
            if (offset >= AllComments.Count) return new List<Comment>();

            var value = AllComments.Count - offset;

            if (value < itemPerPage) return AllComments.GetRange(offset, value);

            return AllComments.GetRange(offset, itemPerPage);
        }
Code language: C# (cs)

ScrollToEnd Event in UITableViewSource

We need to detect when we arrive at the end of the table. And we also need to override the Scrolled method to accomplish that. The idea is to call the action ScrolledToEnd when we are at the end of the scroll.

   public class YourTableViewSource : UITableViewSource
    {
        public Action ScrolledToEnd { get; set; }

        public override void Scrolled(UIScrollView scrollView)
        {
            var offset = scrollView.ContentOffset.Y;

            var maxOffset = scrollView.ContentSize.Height - scrollView.Frame.Size.Height;

            if (maxOffset - offset <= 0)
            {
                ScrolledToEnd?.Invoke();
            }
        }
Code language: C# (cs)

RefreshData

The following code implements the method we just wrote in the TableView, the famous action scrolledToEnd. And it loads our data. So we can call this function in our ViewDidAppear. The _commentsBuffer will be the source of the TableView. For more information read the code comments bellow.

     // The number of items you want to load
        private int _itemsPerPage = 2;

        // All the data already loaded and show in the TableView 
        private List<Comment> _commentsBuffer = new List<Comment>();

        private void RefreshYourData()
        {
            // The first load
            var comments = GetComments(0, _itemsPerPage);

            var source = new YourTableViewSource(_commentsBuffer);

            _commentsBuffer.AddRange(comments);

            source.ScrolledToEnd = async () =>
            {
                try
                {
                    // This call will load the rest of your comments
                    var results = await GetComments(_commentsBuffer.Count, _itemsPerPage);

                    if (results.IsNotNullOrEmpty())
                    {
                        _commentsBuffer.AddRange(results);

                        CommentTableView.ReloadData();
                    }
                }
                catch (Exception ex)
                {
                    // We are in an async void method. Try to always add a try catch in this case
                    ErrorManager.OnError(this, ex);
                }
            };

            // Assign the source
            CommentTableView.Source = source;

            CommentTableView.ReloadData();

            // This part of code is a tricks to scroll to the top when it is the first load
            if (_commentsBuffer.Count > 0)
                CommentTableView.ScrollToRow(NSIndexPath.FromRowSection(0, 0), UITableViewScrollPosition.None, false);
        }
Code language: C# (cs)

(More information about ScrollToRow here)

Conclusion

With this small piece of code, you should be able to deferred the load of the data. Furthermore, now your are able to implement LazyLoading in a TableView.

Happy coding ! 🙂