Skip to content

Instantly share code, notes, and snippets.

@taimila
Created February 5, 2019 07:53
Show Gist options
  • Save taimila/7725d14419371dc165ca62f31dbfb32a to your computer and use it in GitHub Desktop.
Save taimila/7725d14419371dc165ca62f31dbfb32a to your computer and use it in GitHub Desktop.
Xamarin.Forms CardView for iOS (Supports rounded corners, drop shadow and border)
using Xamarin.Forms;
namespace Taimila
{
public class CardView : ContentView
{
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(
propertyName: "CornerRadius",
returnType: typeof(int),
declaringType: typeof(CardView),
defaultValue: 15);
public int CornerRadius
{
get { return (int)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
public static readonly BindableProperty ShadowColorProperty = BindableProperty.Create(
propertyName: "ShadowColor",
returnType: typeof(Color),
declaringType: typeof(CardView),
defaultValue: Color.Black);
public Color ShadowColor
{
get { return (Color)GetValue(ShadowColorProperty); }
set { SetValue(ShadowColorProperty, value); }
}
public static readonly BindableProperty ShadowOpacityProperty = BindableProperty.Create(
propertyName: "ShadowOpacity",
returnType: typeof(float),
declaringType: typeof(CardView),
defaultValue: 0.4f);
public float ShadowOpacity
{
get { return (float)GetValue(ShadowOpacityProperty); }
set { SetValue(ShadowOpacityProperty, value); }
}
public static readonly BindableProperty ShadowRadiusProperty = BindableProperty.Create(
propertyName: "ShadowRadius",
returnType: typeof(float),
declaringType: typeof(CardView),
defaultValue: 5.0f);
public float ShadowRadius
{
get { return (float)GetValue(ShadowRadiusProperty); }
set { SetValue(ShadowRadiusProperty, value); }
}
public static readonly BindableProperty ShadowOffsetXProperty = BindableProperty.Create(
propertyName: "ShadowOffsetX",
returnType: typeof(float),
declaringType: typeof(CardView),
defaultValue: 5.0f);
public float ShadowOffsetX
{
get { return (float)GetValue(ShadowOffsetXProperty); }
set { SetValue(ShadowOffsetXProperty, value); }
}
public static readonly BindableProperty ShadowOffsetYProperty = BindableProperty.Create(
propertyName: "ShadowOffsetY",
returnType: typeof(float),
declaringType: typeof(CardView),
defaultValue: 5.0f);
public float ShadowOffsetY
{
get { return (float)GetValue(ShadowOffsetYProperty); }
set { SetValue(ShadowOffsetYProperty, value); }
}
public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create(
propertyName: "BorderWidth",
returnType: typeof(float),
declaringType: typeof(CardView),
defaultValue: 1f);
public float BorderWidth
{
get { return (float)GetValue(BorderWidthProperty); }
set { SetValue(BorderWidthProperty, value); }
}
public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(
propertyName: "BorderColor",
returnType: typeof(Color),
declaringType: typeof(CardView),
defaultValue: Color.Black);
public Color BorderColor
{
get { return (Color)GetValue(BorderColorProperty); }
set { SetValue(BorderColorProperty, value); }
}
}
}
using System.ComponentModel;
using CoreGraphics;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(Taimila.CardView), typeof(Taimila.iOS.CardViewRenderer))]
namespace Taimila.iOS
{
public class CardViewRenderer : ViewRenderer<CardView, GyroView>
{
protected override void OnElementChanged(ElementChangedEventArgs<CardView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Subviews[0].Layer.CornerRadius = e.NewElement.CornerRadius;
Subviews[0].Layer.MasksToBounds = true;
Subviews[0].Layer.BorderWidth = e.NewElement.BorderWidth;
Subviews[0].Layer.BorderColor = e.NewElement.BorderColor.ToCGColor();
var container = new UIView();
container.MaximumPressure = 10;
container.BackgroundColor = UIColor.Clear;
container.Layer.ShadowColor = e.NewElement.ShadowColor.ToCGColor();
container.Layer.ShadowOffset = new CGSize(e.NewElement.ShadowOffsetX, e.NewElement.ShadowOffsetY);
container.Layer.ShadowOpacity = e.NewElement.ShadowOpacity;
container.Layer.ShadowRadius = e.NewElement.ShadowRadius;
container.AddSubview(Subviews[0]);
SetNativeControl(container);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == CardView.ShadowColorProperty.PropertyName)
base.Layer.ShadowColor = Element.ShadowColor.ToCGColor();
if (e.PropertyName == CardView.ShadowOffsetXProperty.PropertyName &&
e.PropertyName == CardView.ShadowOffsetYProperty.PropertyName)
base.Layer.ShadowOffset = new CGSize(Element.ShadowOffsetX, Element.ShadowOffsetY);
if (e.PropertyName == CardView.ShadowOpacityProperty.PropertyName)
base.Layer.ShadowOpacity = Element.ShadowOpacity;
if (e.PropertyName == CardView.ShadowRadiusProperty.PropertyName)
base.Layer.ShadowRadius = Element.ShadowRadius;
if (e.PropertyName == CardView.BorderWidthProperty.PropertyName)
base.Subviews[0].Layer.BorderWidth = Element.BorderWidth;
if (e.PropertyName == CardView.BorderColorProperty.PropertyName)
base.Subviews[0].Layer.BorderColor = Element.BorderColor.ToCGColor();
if (e.PropertyName == CardView.CornerRadiusProperty.PropertyName)
base.Subviews[0].Layer.CornerRadius = Element.CornerRadius;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment