public void InvalidateClipToBounds() { if (_renderer.NativeView == null) { return; } if (_renderer.NativeView.Layer != null) { /* * MDCInkView * From https://github.com/material-components/material-components-ios-codelabs/blob/master/MDC-111/Swift/Starter/Pods/MaterialComponents/components/Ink/src/MDCInkView.m * MDCInkView uses SuperView's ShadowPath in order to mask the ripple * So we calculate the rounded corners path and we set it to the ShadowPath * but with ShadowOpacity to 0 in order to not overlap the MDCShadowLayer */ _renderer.NativeView.Layer.ShadowPath?.Dispose(); if (_backgroundElement.IsRippleEnabled) { _renderer.NativeView.Layer.ShadowOpacity = 0; _renderer.NativeView.Layer.ShadowPath = BackgroundKit .GetRoundCornersPath(_renderer.NativeView.Layer.Bounds, _backgroundElement.CornerRadius).CGPath; } else { _renderer.NativeView.Layer.ShadowPath = null; } } InvalidateSubViewsMask(); }
private void InvalidateSubViewsMask() { if (_renderer.NativeView.Subviews == null) { return; } var transform = GetMaskTransform(); CGRect bounds; CGPath maskPath; switch (_backgroundElement.BorderStyle) { case BorderStyle.Inner: bounds = _renderer.NativeView.Bounds; maskPath = BackgroundKit.GetRoundCornersPath( bounds, _backgroundElement.CornerRadius).CGPath; break; default: var borderWidth = (float)_backgroundElement.BorderWidth; bounds = _renderer.NativeView.Bounds.Inset(borderWidth, borderWidth); maskPath = BackgroundKit.GetRoundCornersPath( bounds, _backgroundElement.CornerRadius, borderWidth).CGPath; break; } foreach (var subView in _renderer.NativeView.Subviews) { if (subView?.Layer?.Sublayers?.FirstOrDefault( l => l is GradientStrokeLayer) != null) { continue; } subView.Layer.Mask?.Dispose(); subView.Layer.Mask = new CAShapeLayer { Frame = _renderer.NativeView.Bounds, Path = transform == null ? maskPath : new CGPath(maskPath, transform.Value) }; subView.Layer.MasksToBounds = true; } }
public UIBezierPath GetRoundCornersPath(CGRect bounds) => BackgroundKit.GetRoundCornersPath(bounds, _cornerRadius);