custom viewrenderer for UILabel overlaps text inside list view on scroll

I am using a couple of sources to make a custom renderer for a label that can display htmlstring and has data detectors. On android, it works perfectly, but ios implementation has some issues. Here's the ios implementation :

`using System.ComponentModel;
using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(HyperLinkLabel), typeof(HyperLinkLabelRenderer))]
namespace YourNameSpace
{
public class HyperLinkLabelRenderer : ViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);

        var view = (HyperLinkLabel)Element;
        if (view == null) return;

        var attr = new NSAttributedStringDocumentAttributes();
        var nsError = new NSError();
        attr.DocumentType = NSDocumentType.HTML;

        var myHtmlData = NSData.FromString(view.Text, NSStringEncoding.Unicode);

        UITextView uilabelleftside = new UITextView(new CGRect(0, 0, view.Width, view.Height));
        //uilabelleftside.Text = view.Text;
        uilabelleftside.Editable = false;
        uilabelleftside.AttributedText = new NSAttributedString(myHtmlData, attr, ref nsError);
        uilabelleftside.Font = UIFont.SystemFontOfSize((float)view.FontSize);


        // Setting the data detector types mask to capture all types of link-able data
        uilabelleftside.DataDetectorTypes = UIDataDetectorType.All;
        uilabelleftside.BackgroundColor = UIColor.Clear;

        // overriding Xamarin Forms Label and replace with our native control
        SetNativeControl(uilabelleftside);
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == Label.TextProperty.PropertyName)
        {
            var view = (HyperLinkLabel)Element;
            if (view == null) return;

            var attr = new NSAttributedStringDocumentAttributes();
            var nsError = new NSError();
            attr.DocumentType = NSDocumentType.HTML;

            var myHtmlData = NSData.FromString(view.Text, NSStringEncoding.Unicode);

            UITextView uilabelleftside = new UITextView(new CGRect(0, 0, view.Width, view.Height));

            uilabelleftside.AttributedText = new NSAttributedString(myHtmlData, attr, ref nsError);
            uilabelleftside.Font = UIFont.SystemFontOfSize((float)view.FontSize);
            uilabelleftside.Editable = false;

            // Setting the data detector types mask to capture all types of link-able data
            uilabelleftside.DataDetectorTypes = UIDataDetectorType.All;
            uilabelleftside.BackgroundColor = UIColor.Clear;

            // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(uilabelleftside);
        }
    }
}

}
`

When I scroll down or up and an item reappears, it fires OnElementChanged with different values and this causes the text of the renderer to overlap.
Here's my Xaml:

<TabbedPage.ItemTemplate> <DataTemplate> <ContentPage Title="{Binding title}"> <ListView ItemsSource="{Binding Posts}"> <ListView.RowHeight> <OnPlatform x:TypeArguments="x:Int32" iOS="200" Android="220"/> </ListView.RowHeight> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid Padding="8"> <Grid.ColumnDefinitions> <ColumnDefinition Width = "50"/> <ColumnDefinition Width = "*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height = "40"/> <RowDefinition Height = "3"/> <RowDefinition Height = "*"/> <RowDefinition Height = "30"/> </Grid.RowDefinitions> <Image Grid.Column = "0" Grid.Row = "0" Source = "{Binding author.avatar_url}" Aspect = "AspectFill" WidthRequest = "40" HeightRequest = "40" HorizontalOptions = "Center" VerticalOptions = "Center"/> <Grid Grid.Column = "1"> <Grid.ColumnDefinitions> <ColumnDefinition Width = "*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height = "15"/> <RowDefinition> <OnPlatform x:TypeArguments = "GridLength" iOS="10" Android="15" /> </RowDefinition> </Grid.RowDefinitions> <Label Grid.Row = "0" Style = "{StaticResource authorName}" Text="{Binding author.full_name}" /> <Label Grid.Row = "1" Style = "{StaticResource proffInfo}" Text="{Binding author.proffInfo}" /> </Grid> <Grid x:Name = "postContent" Grid.Row = "2" Grid.Column = "0" Grid.ColumnSpan = "2" > <Grid.RowDefinitions> <RowDefinition Height = "30"/> <RowDefinition Height = "*"/> </Grid.RowDefinitions> <Label Grid.Row = "0 " Style = "{StaticResource heading1}" Text = "{Binding title}" /> <!--<WebView Grid.Row = "1"> <WebView.Source> <HtmlWebViewSource Html="{Binding html_content}"/> </WebView.Source> </WebView>--> <renderers:HyperLinkLabel Grid.Row = "1" Text="{Binding html_content}" /> </Grid> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage> </DataTemplate> </TabbedPage.ItemTemplate>

The xaml shouldn't be an issue cause it renders on android just fine.

Answers

Sign In or Register to comment.