maui icon indicating copy to clipboard operation
maui copied to clipboard

[iOS] LinearGradientBrush spills outside view background

Open derlidio opened this issue 2 years ago • 16 comments

Description

If you apply a LinearGradientBrush to the background of a BoxView, it will fill the BoxView area, but also all the way down to the end of the page. Happens only on iOS. Tested on 16.4 and 17 (simulators). Not tested on physical device.

Microsoft. Maui.Controls - 8.0.0-rc.2.9530 Microsoft.Maui.Controls.Compatibility - 8.0.0-rc.2.9530

Steps to Reproduce

  1. Create a new .NET MAUI app
  2. Add a static resource defining a LinearGradientBrush
  3. Add a BoxView anywhere inside the VerticalStackLayout and set its Background to the LinearGradientBrush

Resource:

    <ContentPage.Resources>
        <LinearGradientBrush x:Key="bg" StartPoint="0,0.5" EndPoint="1,0.5">
            <GradientStop Color="#FFFF0000" Offset="0"/>
            <GradientStop Color="#FF00FF00" Offset="0.5"/>
            <GradientStop Color="#FF0000FF" Offset="1"/>
        </LinearGradientBrush>
    </ContentPage.Resources>

BoxView:

<BoxView HeightRequest="8" Background="{StaticResource bg}"/>

Link to public reproduction project repository

No response

Version with bug

8.0.0-rc.2.9511

Is this a regression from previous behavior?

Yes, this used to work in Xamarin.Forms

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 17

Did you find any workaround?

If it's only for decoration, instead of using a BoxView, use a Rectangle and set it's Fill property.

Relevant log output

No response

derlidio avatar Nov 09 '23 23:11 derlidio

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

ghost avatar Nov 10 '23 15:11 ghost

Possibly related: https://github.com/dotnet/maui/issues/18671

I've seen a similar issue using a RoundRectangle, where it spills out of the control on iOS. This was happening only on the initial load. If I had a button that set the gradient brush after it was fully loaded, it would work properly. It also worked properly if I just used a solid color brush.

john-hollander avatar Nov 15 '23 15:11 john-hollander

I have the same issue when setting the Background of a Button to a LinearGradientBrush - all of my buttons appear to extend to the bottom and right edges of the screen.

timjamwoo avatar Jan 30 '24 09:01 timjamwoo

I have the same issue using a linear gradient brush with a button

AdamDiament avatar Jan 30 '24 14:01 AdamDiament

I'm seeing the same issue buttons and grids

WebGoose avatar Feb 27 '24 13:02 WebGoose

We have refactored all our MAUI buttons to SyncFusion buttons in the absence of a fix for this fron the MAUI team thus far. tbh they are better, they support adding any content via a content view.

AdamDiament avatar Feb 27 '24 15:02 AdamDiament

I have the same issue. Is there any update on this or a suggested workaround?

SteHiggins avatar Feb 29 '24 16:02 SteHiggins

I have the same issue

19bartek92 avatar Mar 03 '24 13:03 19bartek92

My current intention for a workaround for this is to do something like below - interested in other people's thoughts on this.

public class GradientButton : Button
{
    protected override async void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);

        await SetBackground();
    }

    private async Task SetBackground()
    {
        await Task.Delay(50);
        var hasValue = App.Current.Resources.TryGetValue("RectangleGradientHorizontal", out object gradient);

        if (hasValue)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                Background = (LinearGradientBrush)gradient;
            });
        }
    }
}

SteHiggins avatar Mar 04 '24 13:03 SteHiggins

Linking to a test repo in case it helps https://github.com/jump32/maui-app-gradient-issue

We are seeing the same issue. Note the repo uses Maui.Controls 8.0.7 and the issue still persists.

jump32 avatar Mar 12 '24 12:03 jump32

Can you try using a Border instead of a BoxView? Also be sure to try with the latest 8.0.21 version of MAUI.

I was able to reproduce the issue in the repro posted by @jump32 on iOS only (MacCatalyst interestingly did not repro). I changed the code to use a Border instead and was able to work around the issue that way.

Redth avatar May 06 '24 17:05 Redth

I can confirm that the Border workaround works for me as well.

jump32 avatar May 08 '24 10:05 jump32

The border workaround works. But I'm surprised that the actual problem is still there in VS 17.10.3 (Maui controls 8.0.61). And that after more than 6 months ?!?

EddyCelis avatar Jul 06 '24 21:07 EddyCelis

This appears to be affecting all views maybe? I have seen this also on Button at some point this week.

mattleibow avatar Jul 23 '24 22:07 mattleibow

@mattleibow this might be the ticket you are referring to when you said it affects buttons as well: #20218

afk013 avatar Jul 29 '24 10:07 afk013

This appears to be affecting all views maybe? I have seen this also on Button at some point this week.

I can confirm that it affects contentviews and layouts.

ouijahija avatar Oct 22 '24 08:10 ouijahija

Please pay attention to this issue!

maonaoda avatar Oct 31 '24 06:10 maonaoda

In StaticCAGradientLayer`s AddAnimation

Can see that this first Bound(430,108) is real size and then the Bound(430,108) is reseted to (430,932) Image

Image

maonaoda avatar Oct 31 '24 06:10 maonaoda

This line https://github.com/albyrock87/maui/blob/72a01411bcae2a0c259685bb20ba9ec4d5e6be2f/src/Core/src/Platform/iOS/ContentView.cs#L30

maonaoda avatar Oct 31 '24 06:10 maonaoda

Is it unwise to change all Sublayers? Image

maonaoda avatar Oct 31 '24 07:10 maonaoda

My personal temporary workaround: Change the name of BackgroundLayer that i want to use to a string other than MauiBackgroundLayer which is the maui`s BackgroundLayerName

maonaoda avatar Oct 31 '24 07:10 maonaoda

My personal temporary workaround: Change the name of BackgroundLayer that i want to use to a string other than MauiBackgroundLayer which is the maui`s BackgroundLayerName

Would you mind explaining how you exactly do that? Or point me to where I can read up on that? My current workaround is to just not use GradientBrushes on iOS and so any workaround would be better :)

ouijahija avatar Oct 31 '24 08:10 ouijahija

For some reason I need to override UpdateBackground for my own BaseContentPage which i use GradientBrushes as Background. public abstract class BaseContentPage : ContentPage by using this:

        internal static void RemapForControls()
        {
            BaseContentPageHandler.Mapper.ReplaceMapping<BaseContentPage, BaseContentPageHandler>(nameof(Background), (handler, baseContentPage) =>
            {
                if (handler is IPlatformViewHandler invh && invh.ViewController is not null)
                {
                    invh.ViewController.View?.UpdateBackground(baseContentPage);
                }
            });
        }

And then Convert Maui's code into your own implementation

        internal const string BackgroundLayerName = "BaseContentPageBackgroundLayer";

        public static void UpdateBackground(this UIView platformView, BaseContentPage view)
        {
            platformView.UpdateBackground(view.Background, view as IButtonStroke,
                view.Direction == Directions.Horizontal && view is not UserMigrationPage, view.BackgroundColor);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="platformView"></param>
        /// <param name="paint"></param>
        /// <param name="stroke"></param>
        /// <param name="useSafeArea"></param>
        public static void UpdateBackground(this UIView platformView, Paint? paint, IButtonStroke? stroke = null, bool useSafeArea = false, Color? color = null)
        {
        ...  Here you can change the backgroundLayer.Name to another name to prevent the current maui error code (may be).
       }

https://github.com/dotnet/maui/blob/cb38cfbc271adf3292c78006535409d51ac8dc3f/src/Core/src/Platform/iOS/ViewExtensions.cs#L68-L112

maonaoda avatar Oct 31 '24 09:10 maonaoda