Xamarin.forms: Stacklayout in frame "bleeds" outside of frame's rounded corners in iOS

Created on 9 Apr 2018  路  15Comments  路  Source: xamarin/Xamarin.Forms

Description

When a stacklayout with a background color is put at the top inside a frame with rounded corners, the edges of the stacklayout "bleed" outside of the rounded corners of the frame. This happens in iOS, not on android, where the behavior is correct.

Steps to Reproduce

  1. Open the test project

  2. Build the project and deploy on ios and android

  3. note the difference

Expected Behavior

Stacklayout corners should not bleed outside of the frame

Actual Behavior

Stacklayout corners bleed outside of the frame

Basic Information

  • Version with issue:
  • Last known good version: ?
  • IDE: Visual studio 2017
  • Platform Target Frameworks:

    • iOS: any

  • Nuget Packages: -

Screenshots

Android:
screenshot_20180409-115043-0

iOS:
ios

Reproduction Link

FrameBleed.zip

3 help wanted high impact iOS 馃崕 bug up-for-grabs

Most helpful comment

Its still happening, any workaround?

All 15 comments

the same issue also in UWP

The same issue on iOS and UWP

Seeing this currently in Xamarin.Forms v3.0.0.561731 on iOS

Xamarin.Forms v3.1 has this bug too.

@pauldipietro Any updates? I think this bug affects work of lots of people.

Any updates ? how to use a palliative solution ?

Its still happening, any workaround?

Hi! At work we had the same problem. We found this workaround. In xaml you just have to use it like this:

        <StackLayout.Effects>
            <views:FrameCornerRadius CornerRadius="{OnPlatform Android='10', iOS='15'}" />
        </StackLayout.Effects>

I hope this help you.
Regards

@mariajoserabaza Thanks for sharing your gist, it indeed works. However, you've created corner radius effects for Android and iOS, whereas (at least in my case) the problem was happening only for iOS. For those of you who want to stay as minimalistic in your effects/renderers changes I suggest to create only iOS effect and set MasksToBounds to true(docs & SO post). Following @mariajoserabaza sample, you could have your iOS effect look like this:

public class FrameCornerRadiusEffect : PlatformEffect
{
    protected override void OnAttached()
    {
        Container.Layer.MasksToBounds = true;
    }

    protected override void OnDetached()
    {
    }
}

I have just set IsClippedToBounds to true for the frame in FrameBleed project, and it magically works on iOS, even though it is not required for Android.

Interesting behavior, maybe a number of things have changed since the bug was originally posted. Even though it works now, the behavior is still inconsistent.

@ult-ghasan you saved my day. Best solution is to write own FrameRender and set
Element.IsClippedToBounds = true;
Now Android and iOS will look same

IsClippedToBounds works partially for me.
It is only a workaround if you set it on the frame itself.
But then the shadow effect of the frame does not work anymore.

Setting MasksToBounds = true in iOS custom renderer also results in lack of shadows.
Tested on Xamarin.Forms 4.5.0.356

IsClippedToBounds works partially for me.
It is only a workaround if you set it on the frame itself.
But then the shadow effect of the frame does not work anymore.

As a workaround add another layer of Frame that would just have IsClippedToBounds = true keeping a separate layer of Frame that provides the shadow

I am unable to get the work arounds to resolve the issue on iOS with 4.6.0.847. Setting IsClippedToBounds = True appears to work when the view is initially presented, but when you dynamically change the view (as I have to do), then the CornerRadius on the Frame has no effect. Using the FrameCornerRadiusEffect makes no difference. I can see when debugging that the Container.Layer.MasksToBounds = true already before it is set in the OnAttached. In my case I have a label inside a frame that I am adding to children in C# code. I was able to round the corners on the label of iOS and left the rounded corners on the Frame for Android. This is what I applied to label in iOS
Container.Layer.MaskedCorners = CACornerMask.MaxXMaxYCorner | CACornerMask.MaxXMinYCorner | CACornerMask.MinXMaxYCorner | CACornerMask.MinXMinYCorner;
Container.Layer.CornerRadius = 10;
Container.Layer.MasksToBounds = true;
Container.ClipsToBounds = true;

Was this page helpful?
0 / 5 - 0 ratings