Search code examples
iosxamarinstacklayout

Asynchronously adding the child to stacklayout in xamarin form iOS


I am adding the multiple view as child to a stacklayout in a loop. Page is rendering only after all children are being added. i want to show children that are added and a loading sign for the children which are being added.

i am doing like below,

for(int i= 0; i<30;i++){ myStackLayout.Children.Add(myView); }

How to make it asynchronous.


Solution

  • The easiest way is to run your "content/view creation" on a background thread and then when you need to add that content/view to the UI, add it on the main/UI thread (BeginInvokeOnMainThread).

    Run the content creation on a non-main/UI thread:

    Task.Run(async () =>
    {
        var itemsAdded = await AddContentAsync();
    });
    

    Content creation example:

    Note: We "show" the CREATING CONTENT label, then we create 20 Buttons and add them one at a time on the main/UI thread and also scroll to the new content as it it added, once the content is completed, we scroll back to the top and "hide" the CREATING CONTENT label.

    Task<int> AddContentAsync()
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            topLayout.RaiseChild(loading);
            loading.IsVisible = true;
        });
    
        int itemsAdded = 0;
        for (itemsAdded = 1; itemsAdded < 21; itemsAdded++)
        {
            // Create your dynamic content view....
            var newContentView = new Button
            {
                Text = itemsAdded.ToString(),
                HorizontalOptions = LayoutOptions.CenterAndExpand
            };
    
            Device.BeginInvokeOnMainThread(() =>
            {
                dynamicStackLayout.Children.Add(newContentView);
                (dynamicStackLayout.Parent as ScrollView)?.ScrollToAsync(newContentView, ScrollToPosition.End, true);
            });
        }
    
        Device.BeginInvokeOnMainThread(() =>
        {
            (dynamicStackLayout.Parent as ScrollView)?.ScrollToAsync(0, 0, true);
            loading.IsVisible = false;
            topLayout.RaiseChild(scrollView);
        });
        return itemsAdded;
    }
    

    Results:

    enter image description here