Falko Falko - 29 days ago 9
C# Question

Cell-reusing issue with list view and view cells with custom renderer

I'm trying to display a list view with cells that are rendered with a custom iOS renderer. When scrolling the list, there are nasty overlays (as shown below). I boiled it down to the following lines of code.

The

App
contains a
ListView
with its
ItemsSource
set to a dummy list of all characters from A to Z. The
ItemTemplate
is created with a custom
ItemCell
defined below.

public class App : Application
{
public App()
{
MainPage = new ContentPage {
Content = new ListView {
ItemsSource = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),
ItemTemplate = new DataTemplate(typeof(ItemCell)),
},
};
}
}


The
ItemCell
contains a
Label
bound to the list item.

public class ItemCell: ViewCell
{
public ItemCell()
{
View = new Label();
View.SetBinding(Label.TextProperty, ".");
}
}


On iOS the
Label
is rendered with the following
FixedLabelRenderer
. It sets a native control represented by a
UILabel
containing the
Element
's
Text
.

public class FixedLabelRenderer : ViewRenderer<Label, UILabel>
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);

SetNativeControl(new UILabel(RectangleF.Empty) { Text = Element.Text });
}
}


Now the problem is that, apparently, when reusing a cell, the control is not removed, but only a new one is created. So I'm getting the overlays shown in the screenshots below.



(Left: before scrolling, Right: after scrolling)

Interestingly this issue doesn't happen with Xamarin.Forms 1.2.3 or 1.3.1, but with 1.3.5 and 1.4.0.

Answer

Oh, I found a solution on the Xamarin Forum:

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
            SetNativeControl(new UILabel());

        if (e.NewElement != null)
            Control.Text = e.NewElement.Text;
    }

So basically you need to make sure to only create one UILabel and reuse it afterwards.

Comments