Yes and Maybe No.
Yes: you can create custom renderer for the view types you want to be able to customize, which will give you a link between your XAML and your iOS app. On the iOS side you can perform all the calls to all libraries you need. You can then create attached properties (such as the Style example below) that can hold additional information you may need to configure the render and put these attached properties in a Style resource and use them around your project. Xamarin.Forms doesn't yet support merging resource dictionaries but you can write a bit of code to do that so all your styles would be in one location
however...
Maybe No: there are many predefined controls and their respective renderers in Xamarin.Forms, it will be difficult to create a consistent addon to the framework that works in all scenarios, for example a button inside a ListView may not render correctly (give it a shot)
If you do give it a shot, once you have the basic renderer that works on properties you can package a set of properties together with a Style extension
public class Setter
{
public string Property { get; set; }
public object Value { get; set; }
public string ConverterKey { get; set; }
public object ConverterParameter { get; set; }
}
[ContentProperty ("Children")]
public class Style
{
public ResourceDictionary Resources { get; set; }
public Style ()
{
Children = new List<Setter> ();
}
public List<Setter> Children { get; private set; }
public static readonly BindableProperty StyleProperty =
BindableProperty.CreateAttached<BindableObject, Style> ((bob) => GetStyle (bob), null, BindingMode.OneWay
, propertyChanged: (bindable, oldvalue, newvalue) => {
if (newvalue != null) {
var tinf = bindable.GetType ().GetTypeInfo ();
foreach (var setter in newvalue.Children) {
PropertyInfo pinfo = null;
while (pinfo == null && tinf != null) {
pinfo = tinf.DeclaredProperties.FirstOrDefault (p => p.Name == setter.Property);
if (pinfo == null) {
tinf = tinf.BaseType.GetTypeInfo ();
if (tinf == typeof(object).GetTypeInfo ())
break;
}
}
if (pinfo != null) {
object convertedValue = null;
if (setter.ConverterKey != null && newvalue.Resources != null) {
object valCon;
if (newvalue.Resources.TryGetValue (setter.ConverterKey, out valCon) && valCon != null) {
if (valCon is IValueConverter)
convertedValue = ((IValueConverter)valCon).Convert (setter.Value, pinfo.PropertyType, setter.ConverterParameter, System.Globalization.CultureInfo.CurrentUICulture);
else if (valCon is TypeConverter)
convertedValue = ((TypeConverter)valCon).ConvertFrom (setter.Value);
else
convertedValue = Convert.ChangeType (setter.Value, pinfo.PropertyType);
} else
convertedValue = Convert.ChangeType (setter.Value, pinfo.PropertyType);
} else
convertedValue = Convert.ChangeType (setter.Value, pinfo.PropertyType);
pinfo.SetMethod.Invoke (bindable, new [] { convertedValue });
}
}
}
});
public static Style GetStyle (BindableObject bindable)
{
return (Style)bindable.GetValue (StyleProperty);
}
public static void SetStyle (BindableObject bindable, Style value)
{
bindable.SetValue (StyleProperty, value);
}
}
And in XAML...
<f:Style x:Key="stackStyle">
<f:Style.Resources>
<ResourceDictionary>
<ColorTypeConverter x:Key="colorConverter" />
</ResourceDictionary>
</f:Style.Resources>
<f:Setter Property="BackgroundColor" Value="#3898DC" ConverterKey="colorConverter" />
</f:Style>
...
<StackLayout f:Style.Style="{StaticResource stackStyle}">
...