doorman
doorman

Reputation: 16959

Prevent flickering of visible UICollectionView cells

I am using an infinite scrolling UICollectionView which is bound to a custom ObservableCollection which is in the ViewModel. The cell has only a UITextView which is databound to a string attribute in the model object.

When I start scrolling down I am displaying more items by calling the AddRange on the OservableCollection.

public class MyCollection<T> : ObservableCollection<T>
{
    public MyCollection()
        : base()
    {
    }

    public MyCollection(IEnumerable<T> collection)
        : base(collection)
    {
    }

    public MyCollection(List<T> list)
        : base(list)
    {
    }

    public void AddRange(IEnumerable<T> range)
    {
        foreach (var item in range)
        {             
            Items.Add(item);
        }

        var dispatcher = Mvx.Resolve<IMvxMainThreadDispatcher>();
        dispatcher.RequestMainThreadAction(() =>
        {
            this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, range));
        });
    }
}

The new items are added successfully, however once the collectionview get´s reloaded from the notification change event the visible cell items may flicker and show the wrong data for a split second. Is it possible to prevent the flickering of the visible cells when loading more data into the UICollectionView?

Upvotes: 0

Views: 1394

Answers (1)

pnavk
pnavk

Reputation: 4642

You can create the IndexPath[] array to pass into collectionView.ReloadItems(indexPaths[]) by doing this:

public void AddRange(IEnumerable<T> range)
{
    ...
    ...
    ...

    var originalCount = Count;

    foreach (var item in range)
    {             
        Items.Add(item);
    }

    List<NSIndexPath> reloadPaths = new List<NSIndexPath>();
    for (int i = originalCount; i < Count-1; i++) {
        reloadPaths.Add(NSIndexPath.FromRowSection(i, 0));
    }

    ...
    ...
    ...
}

Then you can execute collectionView.ReloadItems(reloadPaths.ToArray())

Upvotes: 1

Related Questions