--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<controls:TestContentPage
+ xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:controls="clr-namespace:Xamarin.Forms.Controls"
+ x:Class="Xamarin.Forms.Controls.Issues.Issue5108">
+ <ScrollView>
+ <StackLayout>
+ <Frame BackgroundColor="#2257BABE" BorderColor="#57BABE" CornerRadius="10" Margin="20" x:Name="myframe">
+ <StackLayout Spacing="0">
+ <StackLayout Orientation="Horizontal" Margin="0, 5, 0, 20">
+ <Label class="RadioText" HorizontalOptions="StartAndExpand" VerticalTextAlignment="Start" FontAttributes="Bold">Please review and confirm that you agree to our terms and conditions before continuing.</Label>
+ <Button Text="View" class="Primary" HorizontalOptions="End" VerticalOptions="Start" BorderRadius="8" WidthRequest="80"></Button>
+ </StackLayout>
+ <StackLayout Orientation="Horizontal" Margin="0, 5, 0, 5">
+ <Label class="RadioText" FontAttributes="Bold" VerticalTextAlignment="Center">I agree</Label>
+ <Switch x:Name="rbTerms" HorizontalOptions="StartAndExpand" />
+ <Button x:Name="btnContinue" StyleClass="Primary" Text="Continue" HorizontalOptions="Center" BorderRadius="8" IsEnabled="False" WidthRequest="150"></Button>
+ </StackLayout>
+ </StackLayout>
+ </Frame>
+ <Label Text="Toggle the HasShadow property of the frame:" Style="{DynamicResource CaptionStyle}" />
+ <Button Text="Toggle HasShadow" x:Name="HasShadowButton" />
+ <Label Text="Check if the Shadow layer updates its properties following the 'shadowee' layer:" Style="{DynamicResource CaptionStyle}" />
+ <Button Text="Update Margin" x:Name="MarginButton" />
+ <Button Text="Update Corner Radius" x:Name="RadiusButton" />
+ <Label Text="Toggle the Frame's Background to see how the shadow layer reacts. A background with alpha == 1, the shadow should be darker." Style="{DynamicResource CaptionStyle}" />
+ <Button Text="Update Background" x:Name="BackgroundButton" />
+ </StackLayout>
+ </ScrollView>
+</controls:TestContentPage>
--- /dev/null
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+using Xamarin.Forms.Xaml;
+using System;
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if APP
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Github, 5108, "iOS: Frame with HasShadow set to true and BackgroundColor alpha < 1 casts shadow on all child views", PlatformAffected.iOS)]
+ public partial class Issue5108 : TestContentPage
+ {
+ public Issue5108()
+ {
+ InitializeComponent();
+ MarginButton.Clicked += MarginButton_Clicked;
+ HasShadowButton.Clicked += HasShadowButton_Clicked;
+ RadiusButton.Clicked += RadiusButton_Clicked;
+ BackgroundButton.Clicked += BackgroundButton_Clicked;
+ }
+
+ protected override void Init()
+ {
+ }
+
+
+ void MarginButton_Clicked(object sender, EventArgs e)
+ {
+ if (myframe.Margin.Top == 20)
+ myframe.Margin = new Thickness(5);
+ else
+ myframe.Margin = new Thickness(20);
+ }
+
+ void HasShadowButton_Clicked(object sender, EventArgs e)
+ {
+ myframe.HasShadow = !myframe.HasShadow;
+ }
+
+ void RadiusButton_Clicked(object sender, EventArgs e)
+ {
+ if (myframe.CornerRadius == 10)
+ myframe.CornerRadius = 20;
+ else
+ myframe.CornerRadius = 10;
+ }
+
+ Color? initialColor = null;
+ void BackgroundButton_Clicked(object sender, EventArgs e)
+ {
+ if (!initialColor.HasValue)
+ initialColor = myframe.BackgroundColor;
+
+ if (myframe.BackgroundColor == initialColor.Value)
+ myframe.BackgroundColor = Color.HotPink;
+ else
+ myframe.BackgroundColor = initialColor.Value;
+ }
+ }
+#endif
+}
<Compile Include="$(MSBuildThisFileDirectory)Issue8008.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue6640.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7556.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Issue5108.xaml.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue7329.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7290.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7240.cs" />
<Compile Update="$(MSBuildThisFileDirectory)Issue6254.xaml.cs">
<DependentUpon>Issue6254.xaml</DependentUpon>
</Compile>
+ <Compile Update="$(MSBuildThisFileDirectory)Issue5108.xaml.cs">
+ <DependentUpon>Issue5108.xaml</DependentUpon>
+ </Compile>
<Compile Update="$(MSBuildThisFileDirectory)Issue7357.xaml.cs">
<DependentUpon>Issue7357.xaml</DependentUpon>
</Compile>
</Compile>
<Compile Update="$(MSBuildThisFileDirectory)Issue7865.xaml.cs">
<DependentUpon>Issue7865.xaml</DependentUpon>
- </Compile>
+ </Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue1455.xaml">
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue5108.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue7357.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue7803.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
- </EmbeddedResource>
+ </EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue7048.xaml">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
{
public ViewModelIssue2()
{
-
+
}
}
{
public ModelIssue2()
{
-
+
}
}
}
\ No newline at end of file
using System.ComponentModel;
using System.Drawing;
+using CoreAnimation;
+using CoreGraphics;
using UIKit;
namespace Xamarin.Forms.Platform.iOS
{
public class FrameRenderer : VisualElementRenderer<Frame>
{
+ ShadowView _shadowView;
+
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
else
Layer.BackgroundColor = Element.BackgroundColor.ToCGColor();
+ if (Element.BorderColor == Color.Default)
+ Layer.BorderColor = UIColor.Clear.CGColor;
+ else
+ {
+ Layer.BorderColor = Element.BorderColor.ToCGColor();
+ Layer.BorderWidth = 1;
+ }
+
if (Element.HasShadow)
{
+ if (_shadowView == null)
+ {
+ _shadowView = new ShadowView(Layer);
+ SetNeedsLayout();
+ }
+ _shadowView.UpdateBackgroundColor();
+ _shadowView.Layer.CornerRadius = Layer.CornerRadius;
+ _shadowView.Layer.BorderColor = Layer.BorderColor;
+ }
+ else
+ {
+ if (_shadowView != null)
+ {
+ _shadowView.RemoveFromSuperview();
+ _shadowView.Dispose();
+ _shadowView = null;
+ }
+ }
+
+ Layer.RasterizationScale = UIScreen.MainScreen.Scale;
+ Layer.ShouldRasterize = true;
+ }
+
+ public override void LayoutSubviews()
+ {
+ if (_shadowView != null)
+ {
+ if (_shadowView.Superview == null)
+ Superview.InsertSubviewBelow(_shadowView, this);
+
+ _shadowView?.SetNeedsLayout();
+ }
+ base.LayoutSubviews();
+ }
+
+ class ShadowView : UIView
+ {
+ CALayer _shadowee;
+ CGRect _previousBounds;
+ CGRect _previousFrame;
+
+ public ShadowView(CALayer shadowee)
+ {
+ _shadowee = shadowee;
Layer.ShadowRadius = 5;
Layer.ShadowColor = UIColor.Black.CGColor;
Layer.ShadowOpacity = 0.8f;
Layer.ShadowOffset = new SizeF();
+ Layer.BorderWidth = 1;
}
- else
- Layer.ShadowOpacity = 0;
- if (Element.BorderColor == Color.Default)
- Layer.BorderColor = UIColor.Clear.CGColor;
- else
+ public void UpdateBackgroundColor()
{
- Layer.BorderColor = Element.BorderColor.ToCGColor();
- Layer.BorderWidth = 1;
+ //Putting a transparent background under any shadowee having a background with alpha < 1
+ //Giving the Shadow a background of the same color when shadowee background == 1.
+ //The latter will result in a 'darker' shadow as you would expect from something that
+ //isn't transparent. This also mimics the look as it was before with non-transparent Frames.
+ if (_shadowee.BackgroundColor.Alpha < 1)
+ BackgroundColor = UIColor.Clear;
+ else
+ BackgroundColor = new UIColor(_shadowee.BackgroundColor);
}
- Layer.RasterizationScale = UIScreen.MainScreen.Scale;
- Layer.ShouldRasterize = true;
+ public override void LayoutSubviews()
+ {
+ if (_shadowee.Bounds != _previousBounds || _shadowee.Frame != _previousFrame)
+ {
+ base.LayoutSubviews();
+ SetBounds();
+ }
+ }
+
+ void SetBounds()
+ {
+ Layer.Frame = _shadowee.Frame;
+ Layer.Bounds = _shadowee.Bounds;
+ _previousBounds = _shadowee.Bounds;
+ _previousFrame = _shadowee.Frame;
+ }
}
}
}
\ No newline at end of file