Я создаю кроссплатформенное приложение для xamarin.forms.Мне нужен был пользовательский рендер с градиентным фоном, и я его создал, и он хорошо работает как на Android, так и на iOS.Однако, когда я хочу изменить цвета градиентного фона, он не работает на iOS.
Test.xaml.cs
namespace KiaiDay
{
public class TesteViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Color _startColor = Color.Green;
public Color SStartColor
{
get => _startColor;
set { _startColor = value; OnPropertyChanged(nameof(SStartColor)); }
}
private Color _endColor = Color.Blue;
public Color EEndColor
{
get => _endColor;
set { _endColor = value; OnPropertyChanged(nameof(EEndColor)); }
}
public ICommand Select
{
get => new Command(() =>
{
SStartColor = Color.Red;
EEndColor = Color.Brown;
});
}
#region INotifyPropertyChanged Implementation
void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged == null)
return;
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class teste : ContentPage
{
public teste()
{
BindingContext = new TesteViewModel();
InitializeComponent();
}
}
}
Test.xaml
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<local:ShadowFrame StartColor="{Binding SStartColor}" EndColor="{Binding EEndColor}" HorizontalOptions="Center" VerticalOptions="Center">
<Label Text="Teste"/>
<local:ShadowFrame.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Command="{Binding Select}"/>
</local:ShadowFrame.GestureRecognizers>
</local:ShadowFrame>
</StackLayout>
</ContentPage.Content>
Пользовательский рендерер в PCL
public class ShadowFrame : Frame
{
public static BindableProperty ElevationProperty = BindableProperty.Create(nameof(Elevation), typeof(float), typeof(ShadowFrame), default(float));
public static readonly BindableProperty StartColorProperty = BindableProperty.Create(nameof(StartColor), typeof(Color), typeof(ShadowFrame), default(Color));
public static readonly BindableProperty EndColorProperty = BindableProperty.Create(nameof(EndColor), typeof(Color), typeof(ShadowFrame), default(Color));
public float Elevation
{
get { return (float)GetValue(ElevationProperty); }
set { SetValue(ElevationProperty, value); }
}
public Color StartColor
{
get { return (Color)GetValue(StartColorProperty); }
set { SetValue(StartColorProperty, value); }
}
public Color EndColor
{
get { return (Color)GetValue(EndColorProperty); }
set { SetValue(EndColorProperty, value); }
}
}
iOS Renderer (я думаю, что проблема здесь)
[assembly: ExportRenderer(typeof(ShadowFrame), typeof(ShadowFrameRenderer))]
namespace KiaiDay.iOS.Renderers
{
public class ShadowFrameRenderer : FrameRenderer
{
CAGradientLayer gradientLayer;
private Color StartColor { get; set; }
private Color EndColor { get; set; }
CGRect rect;
public static void Initialize()
{
// empty, but used for beating the linker
}
public ShadowFrameRenderer() => gradientLayer = new CAGradientLayer();
public override void Draw(CGRect rect)
{
this.rect = rect;
var stack = (ShadowFrame)this.Element;
StartColor = stack.StartColor;
EndColor = stack.EndColor;
CGColor startColor = this.StartColor.ToCGColor();
CGColor endColor = this.EndColor.ToCGColor();
#region for Vertical Gradient
//var gradientLayer = new CAGradientLayer();
#endregion
#region for Horizontal Gradient
//var gradientLayer = new CAGradientLayer()
//{
// StartPoint = new CGPoint(0, 0.5),
// EndPoint = new CGPoint(1, 0.5)
//};
#endregion
gradientLayer.Frame = rect;
gradientLayer.Colors = new CGColor[] {
startColor,
endColor
};
NativeView.Layer.InsertSublayer(gradientLayer, 0);
base.Draw(rect);
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
var stack = (ShadowFrame)e.NewElement;
if (e.OldElement != null || Element == null)
{
return;
}
try
{
this.StartColor = stack.StartColor;
this.EndColor = stack.EndColor;
UpdateShadow();
Draw(rect);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ERROR:", ex.Message);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var stack = (ShadowFrame) sender;
if (e.PropertyName == ShadowFrame.ElevationProperty.PropertyName)
{
UpdateShadow();
}
if (e.PropertyName == ShadowFrame.StartColorProperty.PropertyName)
{
this.StartColor = stack.StartColor;
}
if (e.PropertyName == ShadowFrame.EndColorProperty.PropertyName)
{
this.EndColor = stack.EndColor;
}
}
private void UpdateShadow()
{
var shadowFrame = (ShadowFrame)Element;
// Update shadow to match better material design standards of elevation
Layer.ShadowRadius = shadowFrame.Elevation;
Layer.ShadowColor = UIColor.Gray.CGColor;
Layer.ShadowOffset = new CGSize(2, 2);
Layer.ShadowOpacity = 0.80f;
Layer.ShadowPath = UIBezierPath.FromRect(Layer.Bounds).CGPath;
Layer.MasksToBounds = false;
}
}
}
Я хотел бы обновить представление iOS сразу после изменения цвета черезкоманда.