Skip to content

Commit

Permalink
feat: Avoid faux linear gradients on borders on iOS and macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed May 8, 2024
1 parent 3146964 commit 9c139f7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
using Uno.UI.RuntimeTests.Helpers;
using static Private.Infrastructure.TestServices;

#if WINAPPSDK
using Uno.UI.Extensions;
#elif __IOS__
using UIKit;
#elif __MACOS__
using AppKit;
#else
#endif

#if !HAS_UNO_WINUI
using Microsoft/* UWP don't rename */.UI.Xaml.Controls;
#endif
Expand Down Expand Up @@ -49,4 +58,4 @@ public async Task When_Fluent_And_Theme_Changed()
}
}
}
#endif
#endif
29 changes: 21 additions & 8 deletions src/Uno.UI/UI/Xaml/Controls/Border/BorderLayerRenderer.iOSmacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void OnImageChanged(_Image _)

var borderCALayer = borderBrush switch
{
GradientBrush gradientBorder => gradientBorder.GetLayer(area.Size),
GradientBrush gradientBorder when gradientBorder.CanApplyToBorder(cornerRadius) => gradientBorder.GetLayer(area.Size),
RadialGradientBrush radialBorder => radialBorder.GetLayer(area.Size),
_ => null,
};
Expand All @@ -252,11 +252,11 @@ void OnImageChanged(_Image _)
var borderLayerIndex = parent.Sublayers.Length;
CreateGradientBrushLayers(area, area, parent, sublayers, ref borderLayerIndex, borderCALayer, fillMask);
}
else if (borderBrush is SolidColorBrush scbBorder || borderBrush == null)
else
{
Action onInvalidateRender = () =>
{
CGColor color = Brush.GetFallbackColor(borderBrush);
CGColor color = GetNonGradientBorderColor(borderBrush);
outerLayer.StrokeColor = color;
outerLayer.FillColor = color;

Expand Down Expand Up @@ -382,7 +382,7 @@ imageData.NativeImage is _Image uiImage &&

var borderCALayer = borderBrush switch
{
GradientBrush gradientBorder => gradientBorder.GetLayer(area.Size),
GradientBrush gradientBorder when gradientBorder.CanApplyToBorder(cornerRadius) => gradientBorder.GetLayer(area.Size),
RadialGradientBrush radialBorder => radialBorder.GetLayer(area.Size),
_ => null,
};
Expand All @@ -400,12 +400,13 @@ imageData.NativeImage is _Image uiImage &&
var borderLayerIndex = parent.Sublayers.Length;
CreateGradientBrushLayers(area, area, parent, sublayers, ref borderLayerIndex, borderCALayer, fillMask);
}
else if (borderBrush is SolidColorBrush scbBorder)
else
{
Action onInvalidateRender = () => layer.FillColor = Brush.GetFallbackColor(borderBrush);
Action onInvalidateRender = () => layer.FillColor = GetNonGradientBorderColor(borderBrush);

onInvalidateRender();
scbBorder.InvalidateRender += onInvalidateRender;
new DisposableAction(() => scbBorder.InvalidateRender -= onInvalidateRender).DisposeWith(disposables);
borderBrush.InvalidateRender += onInvalidateRender;
new DisposableAction(() => borderBrush.InvalidateRender -= onInvalidateRender).DisposeWith(disposables);
}
}

Expand Down Expand Up @@ -442,6 +443,18 @@ imageData.NativeImage is _Image uiImage &&
return disposables;
}

private static Color GetNonGradientBorderColor(Brush borderBrush)
{
if (borderBrush is LinearGradientBrush linearGradientBrush && linearGradientBrush.SupportsFauxGradientBorder())
{
return linearGradientBrush.MajorStopColor ?? linearGradientBrush.FallbackColorWithOpacity;
}
else
{
return Brush.GetFallbackColor(borderBrush);
}
}

/// <summary>
/// Get a path that describes the rounded border.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Media/LinearGradiientBrush.faux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal override bool CanApplyToBorder(CornerRadius cornerRadius)
#if __WASM__
return cornerRadius == CornerRadius.None;
#elif __IOS__ || __MACOS__
return RelativeTransform == null;
return cornerRadius == CornerRadius.None && RelativeTransform == null;
#else
return true;
#endif
Expand Down

0 comments on commit 9c139f7

Please sign in to comment.