Skip to content

Commit

Permalink
Clip Border content based on StrokeShape property
Browse files Browse the repository at this point in the history
  • Loading branch information
jsuarezruiz authored and rmarinho committed Jun 23, 2022
1 parent 1585906 commit d4707e6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
95 changes: 94 additions & 1 deletion src/Core/src/Platform/iOS/ContentView.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
using System;
using CoreAnimation;
using CoreGraphics;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Graphics.Platform;

namespace Microsoft.Maui.Platform
{
public class ContentView : MauiView
public class ContentView : MauiView, IDisposable
{
IBorderStroke? _clip;
CAShapeLayer? _childMaskLayer;

public override CGSize SizeThatFits(CGSize size)
{
if (CrossPlatformMeasure == null)
Expand All @@ -29,6 +34,11 @@ public override void LayoutSubviews()

CrossPlatformMeasure?.Invoke(bounds.Width, bounds.Height);
CrossPlatformArrange?.Invoke(bounds);

if (ChildMaskLayer != null)
ChildMaskLayer.Frame = bounds;

SetClip();
}

public override void SetNeedsLayout()
Expand All @@ -37,7 +47,90 @@ public override void SetNeedsLayout()
Superview?.SetNeedsLayout();
}

public new void Dispose()
{
DisposeClip();

base.Dispose();
}

internal Func<double, double, Size>? CrossPlatformMeasure { get; set; }
internal Func<Rect, Size>? CrossPlatformArrange { get; set; }

internal IBorderStroke? Clip
{
get { return _clip; }
set
{
_clip = value;

SetClip();
}
}

CAShapeLayer? ChildMaskLayer
{
get => _childMaskLayer;
set
{
var layer = GetChildLayer();

if (layer != null && _childMaskLayer != null)
layer.Mask = null;

_childMaskLayer = value;

if (layer != null)
layer.Mask = value;
}
}

CALayer? GetChildLayer()
{
if (Subviews.Length == 0)
return null;

var child = Subviews[0];

if (child.Layer == null || child.Layer.Sublayers == null)
return null;

return child.Layer;
}

void DisposeClip()
{
if (Subviews.Length == 0)
return;

var mask = ChildMaskLayer;

if (mask == null && Clip == null)
return;

ChildMaskLayer = null;
}

void SetClip()
{
if (Subviews.Length == 0)
return;

var mask = ChildMaskLayer;

if (mask == null && Clip == null)
return;

mask ??= ChildMaskLayer = new CAShapeLayer();

var frame = Frame;

var bounds = new RectF(0, 0, (float)frame.Width, (float)frame.Height);

IShape? clipShape = Clip?.Shape;
var path = clipShape?.PathForBounds(bounds);
var nativePath = path?.AsCGPath();
mask.Path = nativePath;
}
}
}
7 changes: 7 additions & 0 deletions src/Core/src/Platform/iOS/StrokeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,28 @@ internal static void UpdateMauiCALayer(this UIView platformView, IBorderStroke?
if (backgroundLayer is MauiCALayer mauiCALayer)
{
backgroundLayer.Frame = platformView.Bounds;

if (border is IView v)
mauiCALayer.SetBackground(v.Background);
else
mauiCALayer.SetBackground(new SolidPaint(Colors.Transparent));

mauiCALayer.SetBorderBrush(border?.Stroke);
mauiCALayer.SetBorderWidth(border?.StrokeThickness ?? 0);
mauiCALayer.SetBorderDash(border?.StrokeDashPattern, border?.StrokeDashOffset ?? 0);
mauiCALayer.SetBorderMiterLimit(border?.StrokeMiterLimit ?? 0);

if (border != null)
{
mauiCALayer.SetBorderLineJoin(border.StrokeLineJoin);
mauiCALayer.SetBorderLineCap(border.StrokeLineCap);
}

mauiCALayer.SetBorderShape(border?.Shape);
}

if (platformView is ContentView contentView)
contentView.Clip = border;
}
}
}
1 change: 1 addition & 0 deletions src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
Microsoft.Maui.Platform.ContentView.Dispose() -> void
override Microsoft.Maui.Platform.ContentView.SetNeedsLayout() -> void
override Microsoft.Maui.Platform.LayoutView.HitTest(CoreGraphics.CGPoint point, UIKit.UIEvent? uievent) -> UIKit.UIView!
override Microsoft.Maui.Platform.LayoutView.SetNeedsLayout() -> void
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
Microsoft.Maui.Platform.ContentView.Dispose() -> void
override Microsoft.Maui.Platform.ContentView.SetNeedsLayout() -> void
override Microsoft.Maui.Platform.LayoutView.HitTest(CoreGraphics.CGPoint point, UIKit.UIEvent? uievent) -> UIKit.UIView!
override Microsoft.Maui.Platform.LayoutView.SetNeedsLayout() -> void
Expand Down

0 comments on commit d4707e6

Please sign in to comment.