Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 58056

Running into issues with a frame CustomRenderer for iOS

$
0
0

Hello,

I wrote a custom renderer for my chat application to create a chat bubble using a path with series of arcs and lines. On android it works very well but on iOS, I do not see the path being renderered inside when the custom frame is being rendered in a listview. Outside a listview, it gives me what I want. I am starting to suspect that it has to do with the listview.

Can someone give me a hand with this?

some screenshots in android & ios

rendered in iOS
rendered in android

.cs Code:

    public class ChatBubbleRenderer : VisualElementRenderer<ChatBubbleFrame>
    {
         public override void Draw(CGRect rect)
          {
            var currentContext = UIGraphics.GetCurrentContext();
            var properRect = AdjustForThickness(rect);
            HandleShapeDraw(currentContext, properRect);
         }

    protected RectangleF AdjustForThickness(CGRect rect)
    {
        var x = rect.X + Element.Padding.Left;
        var y = rect.Y + Element.Padding.Top;
        var width = rect.Width - ((Element.Padding.Left + (int)Element.StrokeWidth) * 2);
        var height = rect.Height - ((Element.Padding.Top + (int)Element.StrokeWidth) * 2);
        return new RectangleF((float)x, (float)y, (float)width, (float)height);
    }

    protected void HandleShapeDraw(CGContext currentContext, RectangleF rect)
    {
        this.ClipsToBounds = false;
        var path = new CGPath();
        var cr = Element.CornerRadius;
        var hl = Element.HandleLength;
        var x = rect.Left;
        var y = rect.Top;
        var startLeft = x;
        var startTop = y;
        var startRight = rect.Right;
        var startBottom = rect.Bottom;
        var centerX = x + cr;
        var centerY = y + cr;
        var width = (float)rect.Width - hl;
        var height = (float)rect.Height;

        if (Element.HandleIsBottomRight)
        {
            path.AddArc(centerX, centerY, cr, (float)Math.PI, (float)Math.PI * 3f / 2f, false);
            x = startRight - cr;
            //line to top right arc
            path.AddLineToPoint(x, y);

            //top right arc
            centerX = x;
            path.AddArc(centerX, centerY, cr, (float)Math.PI * 3f / 2f, 0, false);
            x = x + cr;

            //bring y down to top of triangle
            y = y + height;
            path.AddLineToPoint(x, y);

            //chat handle
            x = x + hl;
            y = y + hl;
            path.AddLineToPoint(x, y);
            //to bottom left arc

            x = startLeft + cr;
            path.AddLineToPoint(x, y);

            //bottom left arc
            centerX = x;
            centerY = y - cr;
            path.AddArc(centerX, centerY, cr, (float)Math.PI / 2f, (float)Math.PI, false); //false to rotate clockwise
        }
        else
        {
            //line to top right arc
            path.MoveToPoint(x, y);
            x = startRight - cr;
            path.AddLineToPoint(x, y);

            //top right arc
            centerX = x;
            path.AddArc(centerX, centerY, cr, (float)Math.PI * 3f / 2f, 0, false);

            //line to bottom right arc
            x = x + cr;
            y = y + height - cr;
            path.AddLineToPoint(x, y);

            //bottom right arc
            centerX = x - cr;
            centerY = y;
            path.AddArc(centerX, centerY, cr, 0f, (float)Math.PI / 2f, false);

            //line to bottom left arc
            x = startLeft + cr;
            y = y + cr;
            path.AddLineToPoint(x, y);

            //bottom left arc
            centerX = x;
            centerY = y - cr;
            path.AddArc(centerX, centerY, cr, (float)Math.PI / 2f, (float)Math.PI, false); //false to rotate clockwise

            //line to handle
            x = startLeft;
            y = startTop + hl;
            path.AddLineToPoint(x, y);
            x = x - hl;
            y = startTop;
            path.AddLineToPoint(x, y);
        }            

        path.CloseSubpath();
        HandleStandardDraw(currentContext, rect, () => currentContext.AddPath(path));
    }

    /// <summary>
    /// A simple method for handling our drawing of the shape. This method is called differently for each type of shape
    /// </summary>
    /// <param name="currentContext">Current context.</param>
    /// <param name="rect">Rect.</param>
    /// <param name="createPathForShape">Create path for shape.</param>
    /// <param name="lineWidth">Line width.</param>
    protected virtual void HandleStandardDraw(CGContext currentContext, RectangleF rect, Action createPathForShape, float? lineWidth = null)
    {
        currentContext.SetLineWidth(lineWidth ?? Element.StrokeWidth);
        currentContext.SetFillColor(Element.InnerColor.ToCGColor());
        currentContext.SetStrokeColor(Element.StrokeColor.ToCGColor());

        createPathForShape();

        currentContext.DrawPath(CoreGraphics.CGPathDrawingMode.FillStroke);
    }

Xaml

<DataTemplate x:Key="OtherUserCommentTemplate">
            <ViewCell>
                <ViewCell.View>

                            <controls:ChatBubbleFrame x:Name="OtherUserBubble"
                                                      HandleIsBottomRight="False"
                                                      StrokeColor="{StaticResource Color13}"
                                                      InnerColor="White"
                                                      StrokeWidth="1"
                                                      CornerRadius="10"
                                                      HandleLength="7"
                                                      HorizontalOptions="FillAndExpand"
                                                      VerticalOptions="StartAndExpand"
                                                      Padding="-1,10,10,10">
                                <StackLayout Margin="10,10,10,10">
                                    <AbsoluteLayout>
                                        <Label x:Name="OtherUserDisplayName"
                                               Text="{Binding Entity.UserInfoData.DisplayName}"
                                               Style="{StaticResource Typo21}"
                                               Margin="0,0,5,0"
                                               HorizontalOptions="Start"
                                               LineBreakMode="TailTruncation"
                                               AbsoluteLayout.LayoutFlags="PositionProportional"
                                               AbsoluteLayout.LayoutBounds="0,0,-1,-1" />
                                        <Label Text="{Binding Entity.CommentDateTime,Converter={StaticResource DateTimeToPrettyTime}}"
                                               Style="{StaticResource Typo22}"
                                               Grid.Column="1"
                                               Margin="0,0,5,0"
                                               AbsoluteLayout.LayoutFlags="PositionProportional"
                                               AbsoluteLayout.LayoutBounds="0.48,0,-1,-1" />

                                        <controls:ContentButton Command="{Binding Parent[NavigateToIndividualMessageVisibilityPage]}"
                                                                CommandParameter="{Binding Entity}"
                                                                HeightRequest="13"
                                                                Grid.Column="2"
                                                                HorizontalOptions="EndAndExpand"
                                                                AbsoluteLayout.LayoutFlags="PositionProportional"
                                                                AbsoluteLayout.LayoutBounds="1.3,0.01,-1,-1">


                                            <StackLayout Orientation="Horizontal"
                                                         Spacing="4">
                                                <Image Source="{Binding Entity.IsVisibleToClient, Converter={StaticResource VisibleToClientToImage}}"
                                                       WidthRequest="12" />

                                                <Image Source="{Binding Entity.IsVisibleToPartner, Converter={StaticResource VisibleToPartnersToImage}}"
                                                       WidthRequest="12" />
                                            </StackLayout>
                                        </controls:ContentButton>
                                    </AbsoluteLayout>

                                    <Label Text="{Binding Entity.CommentText }"
                                           Style="{StaticResource Typo23}"
                                           LineBreakMode="WordWrap"
                                           Margin="0,6,0,0" />

                                    <controls:FileAttachmentStack Orientation="Vertical"
                                                                  ItemsSource="{Binding Entity.FileAttachmentList}"
                                                                  ItemTemplate="{StaticResource ReceivedMessageImageTemplate}"
                                                                  ItemSelectedCommand="{Binding Parent[DisplayCarousel], Converter={StaticResource ActiveCommandToCommand}}"
                                                                  Spacing="5" />
                                </StackLayout>
                            </controls:ChatBubbleFrame>

                </ViewCell.View>
            </ViewCell>
        </DataTemplate>

Viewing all articles
Browse latest Browse all 58056

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>