[UICollectionView] Performing reloadData as a fallback - Invalid update: invalid number of items in section

0 Answers 907 Views
ListView
Webtoools
Top achievements
Rank 1
Webtoools asked on 08 May 2023, 01:01 PM

Hi, I am new to .NET Maui and Telerik, I'm developing a mobile application that needs to display a list of shops, grouped by city. I also need to open a details page when a specific item is clicked.

I don't have control over the web api providing the data so I have to use it "as is", meaning I'm getting over 1500 items in one go and I am storing it in a local variable.

To create the list I used the RadListView with a GroupDescriptor and it seemd to work fine... it was a bit laggy on startup but acceptable for my use case. However, clicking on an item would cause the application to freeze for several seconds on iOS.

To solve the problem I tried using the LoadOnDemand feature, cycling through the items stored in my local variable and adding them to a ListViewLoadOnDemandCollection, which fixed the original problem but created a new one.

On Android everything works fine but on iOS whenever items are added to the list the app freezes for some time, which increase with every consecutive load. I noticed that my code to load new items is executed istantly but then the rendering takes a lot of time and the following error is displayed in my logs:

Invalid update: invalid number of items in section 8. The number of items contained in an existing section after the update (16) must be equal to the number of items contained in that section before the update (16), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out). Collection view: <TKCollectionView: 0x7fe80a09a400; baseClass = UICollectionView; frame = (0 0; 392 642); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6000020144e0>; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <CALayer: 0x6000027f0700>; contentOffset: {0, 2985.3333333333335}; contentSize: {392, 4200}; adjustedContentInset: {0, 0, 0, 0}; layout: <TKListViewLinearLayout: 0x7fe8099545d0>; dataSource: <Telerik_Maui_Controls_Compatibility_DataControlsRenderer_iOS_TKExtendedListView: 0x7fe80920bde0; frame = (0 0; 392 642); backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <CALayer: 0x6000027f0300>>>

This is my code:

XAML:

<telerik:RadListView ItemsSource="{Binding SourceItems}"
                     x:Name="listView"
                     VerticalScrollBarVisibility="Always"
                     FilterDescriptors="{Binding FilterDescriptors, Mode=OneWayToSource}"
                     IsLoadOnDemandEnabled="{Binding LoadOnDemandEnabled}"
                     LoadOnDemandBufferItemsCount="50"
                     LoadOnDemandMode="Automatic"
                     IsLoadOnDemandActive="{Binding LoadOnDemandActive}"
                     ItemTapped="OnItemSelected">
    [...]
</telerik:RadListView>

ViewModel:

namespace MyApp.ViewModels
{
    public partial class SearchViewModel : ObservableObject
    {
        [ObservableProperty]
        public List<Shop> items;

        [ObservableProperty]
        public ObservableCollection<Shop> sourceItems;

        [ObservableProperty]
        public bool loadOnDemandEnabled = false;

        [ObservableProperty]
        public bool loadOnDemandActive = false;

        public SearchViewModel()
        {
            SourceItems = new ListViewLoadOnDemandCollection(LoadMoreShops);
        }

        public IEnumerable<Shop> LoadMoreShops(CancellationToken cancelationToken)
        {
            ObservableCollection<Shop> result = new ObservableCollection<Shop>();
            LoadOnDemandActive = true;

            try
            {
                int maxIndex = sourceItemsIndex + 50;
                int totalIndex = items != null ? items.Count : 0;
                maxIndex = Math.Min(maxIndex, totalIndex);

                if (maxIndex > sourceItemsIndex)
                {
                    for (int i = sourceItemsIndex; i < maxIndex; i++)
                    {
                        result.Add(Items[i]);
                    }
                }
                else
                {
                    LoadOnDemandEnabled = false;
                    return null;
                }

                sourceItemsIndex = maxIndex + 1;
                LoadOnDemandActive = false;
                return result;
            }
            catch (Exception ex)
            {
                //exception is thrown when the task is canceled. Returning null does not affect the ItemsSource.
                LoadOnDemandActive = false;
                return null;
            }
        }
    }
}
While searching the forum I found a similar issue regarding the ListView for Xamarin Forms (but nothing for MAUI), I'll link the form post in case it might come in handy: https://www.telerik.com/forums/ios-uicollectionview-logs-invalid-update
Didi
Telerik team
commented on 10 May 2023, 03:19 PM

Hi,

Thank you for the provided code and link to the issue reported in Telerik Xamarin ListView control.

I have reviewed the case there and the exception is similar but the behavior happens when the control is grouped, there is also a reordering and item selection. In your case you are using load on demand collection. 

I will send a reply to the support ticket you have opened about the results from my test.

Flotman
Top achievements
Rank 1
commented on 11 Nov 2023, 07:42 PM

Hi, Did you found solution for this issue? I am experiencing similar issue, but in Xamrin Forms, in my case this is happening only when IsLoadOnDemandActive is set back to false, after loading more data. If I don't use IsLoadOnDemandActive the problem is not occurring. 
Didi
Telerik team
commented on 13 Nov 2023, 03:48 PM

Hello, 

The issue reported for the Xamarin ListView is fixed. This is the item: https://feedback.telerik.com/xamarin/1481968-listview-ios-an-error-message-is-presented-when-removing-item-from-the-itemssource-and-then-adding-item 

If you have questions for Telerik Xamarin ListView, open a support ticket for Xamarin. This is the forum for Telerik UI for .NET MAUI. 

No answers yet. Maybe you can help?

Tags
ListView
Asked by
Webtoools
Top achievements
Rank 1
Share this question
or