Exemplo n.º 1
0
        internal static FrameworkElement UpdateMask(UIView owner, UIView superView = null)
        {
            superView = superView ?? owner.Superview;
            var layer = owner.Layer;

            var clippingParentResult = GetClippingParent(owner);

            if (
                clippingParentResult.clippingParent != null &&
                owner is FrameworkElement tfe
#if DEBUG
                && (CanClipSelector?.Invoke(owner) ?? true)
#endif
                )
            {
                var clippingParent = clippingParentResult.clippingParent;

                if (clippingParentResult.child is FrameworkElement cfe && !cfe.ClipChildrenToBounds)
                {
                    // If the immediate child of the clipping parent is not clipping its children, then the
                    // clipping parent is its parent (Ellipse -> Canvas -> Grid -> StackPanel)
                    clippingParent = clippingParentResult.clippingParent.Superview;
                }

                var absolutePosition = ConvertOriginPointToView(owner, clippingParent);

                var clippingBounds = clippingParent.Bounds;

                if (clippingBounds != CGRect.Empty)
                {
                    var maskLayer = new CoreAnimation.CAShapeLayer();
                    var maskRect  = new CGRect(-absolutePosition.X, -absolutePosition.Y, clippingBounds.Width, clippingBounds.Height);
                    maskLayer.Path = UIBezierPath.FromRect(maskRect).CGPath;
                    layer.Mask     = maskLayer;

                    if (typeof(UIElement).Log().IsEnabled(LogLevel.Debug))
                    {
                        typeof(UIElement).Log().LogDebug($"UpdateMask o:{owner.GetType()} p:{clippingParent.GetType()} f:{owner.Frame} b:{owner.Bounds} m:{maskRect} t:{owner.Transform}");
                    }

                    CreateDebugLayer(owner, layer, absolutePosition, clippingBounds);

                    return(clippingParent as FrameworkElement);
                }
                else
                {
                    CreateDebugLayer(owner, layer, absolutePosition, clippingBounds);

                    if (typeof(UIElement).Log().IsEnabled(LogLevel.Debug))
                    {
                        typeof(UIElement).Log().LogDebug($"Mask disabled for CGRect.Empty parent o:{owner.GetType()}/{owner.GetHashCode():X8} p:{clippingParent.GetType()}/{clippingParent.GetHashCode():X8} f:{owner.Frame} b:{owner.Bounds} t:{owner.Transform}");
                    }
                }
            }

            layer.Mask = null;

            return(null);
        }
Exemplo n.º 2
0
        private static void CreateDebugLayer(UIView owner, CALayer layer, CGPoint absolutePosition, CGRect clippingBounds)
        {
            if (FeatureConfiguration.UIElement.ShowClippingBounds)
            {
                if (_debugLayers == null)
                {
                    _debugLayers = new Dictionary <UIView, CALayer>();
                }

                if (_debugLayers.TryGetValue(owner, out var previousLayer))
                {
                    previousLayer.RemoveFromSuperLayer();
                    _debugLayers.Remove(owner);
                }

                var debugLayer    = new CoreAnimation.CAShapeLayer();
                var debugMaskRect = new CGRect(
                    -absolutePosition.X,
                    -absolutePosition.Y,
                    clippingBounds.Width < 1 ? 5 : clippingBounds.Width,
                    clippingBounds.Height < 1 ? 5 : clippingBounds.Height
                    );

                debugLayer.Path      = UIBezierPath.FromRect(debugMaskRect).CGPath;
                debugLayer.Frame     = debugMaskRect;
                debugLayer.LineWidth = 2;

                if (clippingBounds.Width == 0 && clippingBounds.Height == 0)
                {
                    debugLayer.StrokeColor = Colors.Red;
                }
                else if (clippingBounds.Width < 1 || clippingBounds.Height < 1)
                {
                    debugLayer.StrokeColor = Colors.Purple;
                }
                else
                {
                    debugLayer.StrokeColor = Colors.Blue;
                }

                debugLayer.Opaque          = false;
                debugLayer.BackgroundColor = UIColor.Clear.CGColor;
                debugLayer.FillColor       = UIColor.Clear.CGColor;
                debugLayer.MasksToBounds   = false;

                _debugLayers.Add(owner, debugLayer);

                if (layer.Sublayers != null)
                {
                    layer.InsertSublayer(debugLayer, layer.Sublayers.Length);
                }
                else
                {
                    layer.AddSublayer(debugLayer);
                }
            }
        }