XamSvg

Getting Started

Quick start

PCL Mobile App

In your PCL project, add a solution folder images then add a logo.svg file to this folder.
Set the build action of the svg file to Embedded resource (using the properties window).
Then in each of your platform project

  • initialize the XamSvg library
  • add svg to your views

Add the svg component to your app

  • Add the XamSvg component or the XamSvg nuget to all your projects: PCL, Android, iOS and WP81/UWP.

Note that you need a modern PCL profile, ie one with Silverlight unchecked. Read the PCL Profile Change chapter for more informations.

Initialize the XamSvg library

  • Initialize the platform helpers
  • Specify in which assembly/ies to search for svg embedded resources in XamSvg.Shared.Config.ResourceAssembly or XamSvg.Shared.Config.ResourceAssemblies (note that ResourceAssemblies overrides ResourceAssembly)

In this example, we have put the svg image in the PCL project containing the App class. You can use any class contained in the PCL project.

    XamSvg.Setup.InitSvgLib();
    XamSvg.Shared.Config.ResourceAssembly = typeof(App).GetTypeInfo().Assembly;

Optional: enable svg debugging

    XamSvg.Shared.Config.NativeLogger.TraceEnabled = true;

The best place to put the above code is AppDelegate.cs (FinishedLaunching) on iOS, App.xaml.cs on UWP/WP8.1, and on Android in a static singleton in the first Activity or in your Application class. Sample android application class:

    [Application]
    public class MainApp : Application
    {
        public MainApp(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
            XamSvg.Setup.InitSvgLib();
        }
    }

Add svg to your views

On iOS (code)

    image = new UISvgImageView("res:images.logo", fillWidthPixels:0, fillHeightPixels:100);

When setting 0 on a dimension, the svg is scaled using the other dimension and its aspect ratio.
When using contraint based layouts, you may set the width/height of the svg using constraints instead of these width/height properties. You may set one dimension or both dimensions. The UISvgImageView will have an intrinsic content size only if one of the dimension is non zero.

On iOS (if using storyboard instead of code)

  • drag a new Image view
  • set its custom class to UISvgImageView
  • add a custom property with key BundleName, type string, and value res:images.logo. You can add any UISvgImageView property as custom property there as the class is key/value compliant.
  • add contraints so at least one of the width or the height of the image is defined. You can set a placeholder length for a missing dimension to clear contraint errors reported by xcode. It simulates the intrinsic content size the control will have.

On Android (axml layout)

  • declare the xmlns:app namespace in the topmost tag
  • use the new XamSvg.SvgImageView tag and set its specific properties prefixed by app:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
            <XamSvg.SvgImageView
                app:svg="res:images.logo"
                android:layout_width="wrap_content"
                android:layout_height="50dp" />
    </LinearLayout>
    

On WP8.1 / UWP

  • declare the xmlns:app namespace in the topmost tag
  • use the new app:Svg tag and set its specific properties

    <Page
        x:Class="XamSvg.UwDemo.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="using:XamSvg.Universal">
        <Grid Background="DarkSlateGray">
            <Button Click="Button_Click" Padding="0" Margin="0"  BorderThickness="1" BorderBrush="Black" Background="Wheat" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <app:Svg x:Name="MySvg" Source="res:images.logo" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FillMode="Fit" Background="LightBlue" />
            </Button>
        </Grid>
    </Page>
    

Source/BundleName/Svg property

The svg control takes a string as input in the (Source, BundleName or Svg) property. If this string starts with res:, the control search the image in the .net embedded resources.
If this string starts with string:, the control reads the svg image from the string.
Otherwise it will use native platform resources: raw folder for Android, bundle resources for iOS.

res: (.NET embedded resources)

For the res: scheme, don't add the .svg extension, and prefix the file name with the directory path relative to the root of your library, while replacing slash by dots.

For exemple if you have this file:

(PCL Project)/MyFiles/Images/tiger_hood.svg

Use this string:

"res:MyFiles.Images.tiger_hood"

The name is case insensitive. You can use res:myfiles.images.tiger_hood if you prefer.

Don't forget to set the build action of tiger_hood.svg to Embedded Resource !

string: (inline svg)

You can dynamically load a svg using an inline string:

var svgString = @"string:<svg viewBox=""0 0 100 100""><circle cx=""50"" cy=""50"" r=""50"" fill=""#ff0000"" /></svg>"; 

Using a timer, you can easily create an animation with this feature. In the timer, modify and set the svg string again. The control will update the image accordingly.

You can also download the svg string from internet and set it this way.

Android resource (raw)

Note: you should prefer .NET embedded resources (res:) instead.

  • Add a folder called raw under the standard resources folder
  • Add your svg images to this raw folder. Make sure they have the AndroidResource build action.

To display logo.svg:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
            <XamSvg.SvgImageView
                app:svg="@raw/logo"
                android:layout_width="wrap_content"
                android:layout_height="50dp" />
    </LinearLayout>

iOS bunlde resource

Note: you should prefer .NET embedded resources (res:) instead.

To display (ios project)/resources/svg/logo.svg:

    var logo = new UISvgImageView("svg/logo.svg", fillHeightPixels: 80);
    View.Add(logo);

Color Mapping

A color mapping is the transformation of an existing color inside the svg file to another color. This is useful to easily provide a feedback for the pressed state, or to reuse the same svg file using alternate colors.

Colors are specified using the standard HTML syntax: AARRGGBB or RRGGBB
where AA is the alpha level (00=transparent, FF=opaque), and RGB the standard red/green/blue levels.
You can specify color mappings using strings with this syntax:

OLDCOLOR=NEWCOLOR[;OLDCOLOR=NEWCOLOR]...

Examples:

ColorMapping="00000000=ff000000"  
ColorMappingSelected="00000000=ff000000;ffffff=00ff00"

Examples

  • Android Display logo.svg in another color:

    <XamSvg.SvgImageView
        app:svg="res:images.logo"
        app:colorMapping="EAEDF1=494949;FFFFFF=000000;e9f1f7=ffFFFFFE;646464=FFFFFE"
        app:colorMappingSelected="EAEDF1=888888"
        android:layout_width="wrap_content"
        android:layout_height="50dp" />
    

In this example the color EAEDF1, expressed as RRGGBB, is replaced by color 494949.

  • iOS Replace the standard back button with cross.svg in ViewDidLoad:

    var btnBackImage = new UISvgImageView("res:images.cross", fillHeightPixels: NavigationController.NavigationBar.Bounds.Height - 20);
    NavigationItem.LeftBarButtonItem = new UIBarButtonItem(btnBackImage);
    
  • iOS Use a color mapping:

    var hands = new UISvgImageView("res:images.hands", fillHeightPixels: 80, colorMapping: "000000=2471B2", colorMappingSelected: "000000=99FFB2");
    
  • Other examples

Complete example projects with source code are provided. Open and try them, they are easy to understand !
These sample projects are also available on github here and may be updated more frequently.

Mvvmcross target bindings

Mvvmcross is a widely used mvvm framework for native Xamarin apps.

Download the custom target bindings, add them to your iOS/Android projects, and register them from your mvvmcross Setup class.
Then bind using the new "Svg" virtual property.

    public class Setup : MvxAndroidSetup
    {
        protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
        {
            base.FillTargetFactories(registry);
            MvxImageViewSvgDrawableTargetBinding.Register(registry);
        }
    }

Binding usage on Android:

    <XamSvg.SvgImageView
        app:MvxBind="Svg MyStringProperty"
        android:layout_width="wrap_content"
        android:layout_height="50dp" />

Binding usage on iOS:

    set.Bind(icon).For("Svg").To(vm => vm.MyStringProperty);

Optimizing SVG images

Why optimize SVG images ? SVG are images described using mathematical curves. The same image can be described by multiple curves. The idea behind our optimizations is to have the simplest description to speed up parsing and the simplest curves to speed up rendering.

Use the free svg image editor Inkscape to modify and generate optimized svg files, to change the bounding box (which controls the aspect ratio), or to simplify the SVG if it is not displayed correctly. Read the Cleaning and optimizing SVG files chapter of this blog post for full information.

You can then use Internet Explorer or Windows Explorer's preview using this SVG preview extension to verify that your optimized SVG still appears correctly.

Reference

iOS: UISvgImageView

Svg Source

  • string BundleName
  • string BundleString: same as BundleName, but also supports inline svg strings starting with "string:"

Change colors

  • string ColorMapping
  • string ColorMappingSelected

Respect aspect ratio

  • SvgFillMode FillMode: Fit (respect aspect ratio) / Fill (use full space)

Size the image should have. 0x0 to let the OS decides using constraints or Frame

  • nfloat FillWidth
  • nfloat FillHeight

Async loading

  • bool IsLoadAsync: default to true, set to false if the svg must be displayed immediatly

Intelligent reuse

  • bool ShouldClearImageWhenUpdating: default to false

When true, if a property change triggers the redraw of the image, the undelying Image is set to null while loading the updated image. This is required if the control is put in a reused cell and async loading is true, otherwise the old image will be displayed in reused cells while new image is loading. It may also be a problem when updating the colormapping property when async loading is true and this control is outside of a reused cell.

Android: SvgImageView

Svg Source

  • string Svg

Change colors

  • string ColorMapping
  • string ColorMappingSelected

Respect aspect ratio

  • SvgFillMode FillMode: Fit (respect aspect ratio) / Fill (use full space)

Async loading

  • bool IsLoadAsync: default to true, set to false if the svg must be displayed immediatly

Highlighting / Selecting

  • bool IsHighlightOnPressedEnabled
  • bool IsSelectionEnabled

Debugging

  • bool TraceEnabled

UW: Svg

Svg Source

  • string Source

Change colors

  • string ColorMapping
  • string ColorMappingSelected

Respect aspect ratio

  • SvgFillMode FillMode: Fit (respect aspect ratio) / Fill (use full space)

Unsupported features

SVG files can also be exported from Photoshop and Illustrator, as long as they don't contain bitmaps. Bitmap extensions of svg will not render. You can check for bitmap data in a svg file by opening it and looking for tons of raw bytes.

Main unsupported svg features:

  • embedded bitmaps
  • animations
  • mask groups
  • filters
  • named references other than gradients
  • texts (vote for this feature on uservoice)
  • radial gradients are not supported on UWP. Only linear gradients are supported on UWP. Radial gradients are supported on all other platforms.

Note that css style is supported but not recommended: css parsing is slow compared to xml parsing.

Some SVG icon sources

Get in touch!