Skip to content

Instantly share code, notes, and snippets.

@Kikimora
Last active August 17, 2017 08:51
Show Gist options
  • Save Kikimora/470471407226a292dfe063927aa1d62b to your computer and use it in GitHub Desktop.
Save Kikimora/470471407226a292dfe063927aa1d62b to your computer and use it in GitHub Desktop.
#if __IOS__
using PlatformView = UIKit.UIView;
using PlatformViewGroup = UIKit.UIView;
using PlatformTextArea = UIKit.UITextView;
#endif
#if __ANDROID__
using PlatformView = Android.Views.View;
using PlatformViewGroup = Android.Views.ViewGroup;
using PlatformTextArea = Android.Widgets.EditText;
#endif
//Note struct here for extra efficiency
/// <summary>
/// View builder provides methods to build view hierarchy which can be used in Shared code
/// </summary>
public struct ViewBuilder
{
public PlatformViewGroup Parent;
public List<PlatformView> Views;
#if __ANDROID__
public Android.Content.Context Context;
public ViewBuilder(ViewGroup parent, Android.Content.Context context)
{
Parent = parent;
Context = context;
Views = new List<Android.Views.View>();
}
#endif
#if __IOS__
public ViewBuilder(PlatformViewGroup parent)
{
Parent = parent;
Views = new List<PlatformView>();
}
#endif
public T AddSubview<T>(T view) where T : PlatformView
{
Parent.AddSubview(view);
Views.Add(view);
return view;
}
public void Dispose()
{
foreach (var v in Views)
{
v.Dispose();
}
}
}
public struct View
{
public static implicit operator PlatformView(View area) { return area.PlatformView; }
public PlatformView PlatformView { get; set; }
}
public static class ViewUtil
{
public static View View(this ViewBuilder b)
{
#if __IOS__
return new View() { PlatformView = b.AddSubview(new PlatformView()) };
#endif
#if __ANDROID__
return new View() { PlatformView = b.AddSubview(new PlatformView(b.Context)) };
#endif
}
//You can also use View and other wrapper structs here since all of them
//implicitly cnverted to PlatformView subclasses
public static View AddSubview(this View view, PlatformView child)
{
#if __IOS__
view.PlatformView.AddSubview(child);
#endif
#if __ANDROID__
view.PlatformView.AddView(child);
#endif
return view;
}
public static View RemoveFromSuperview(this View view)
{
#if __IOS__
view.PlatformView.RemoveFromSuperview();
#endif
#if __ANDROID__
view.PlatformView.Parent?.RemoveView(view);
#endif
return view;
}
public static View SetBackgroundColor(this View view, RGB color)
{
view.PlatformView.BackgroundColor = color.ToColor();
return view;
}
//Since View is just a struct it is absolutely ok to create it
//as many times as needed. Don't box it and you will be ok.
public static View AsView(this PlatformView view)
{
return new View() { PlatformView = view };
}
}
//Note that struct is used here for extra efficiency.
//Note how simple it is to define own cross platform views!
/// <summary>
/// Text area wrapper compatible with Shared code.
/// </summary>
public struct TextArea
{
public static implicit operator PlatformTextArea(TextArea area) { return area.PlatformView; }
public View AsView() { return new View() { PlatformView = PlatformView }; }
public PlatformTextArea PlatformView { get; set; }
}
/// <summary>
/// View builder extension to build text area control (UITextView on iOS and Android.Widgets.TextArea on Android)
/// </summary>
public static class TextAreaUtil
{
public static TextArea TextArea(this ViewBuilder b)
{
#if __IOS__
return new TextArea() { PlatformView = b.AddSubview(new PlatformTextArea()) };
#endif
#if __ANDROID__
return new TextArea() { PlatformView = b.AddSubview(new PlatformTextArea(b.Context)) };
#endif
}
public static TextArea SetText(this TextArea area, string text)
{
#if __IOS__
area.PlatformView.Text = text;
#endif
#if __ANDROID__
area.PlatformView.SetText(text);
#endif
return area;
}
}
/// <summary>
/// Base view using above infrastructure.
/// </summary>
public class QodenView : PlatformViewGroup
{
#if __IOS__
public QodenView()
{
Builder = new ViewBuilder(this);
}
#endif
#if __ANDROID__
public NewQodenView(Android.Content.Context context)
{
Builder = new ViewBuilder(this, context);
}
#endif
public ViewBuilder Builder;
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
Builder.Dispose();
}
}
}
/// <summary>
/// Common functions to style controls
/// </summary>
public static class NewTheme
{
public static TextArea StyleTextArea(this TextArea area)
{
area.AsView().SetBackgroundColor(RGB.Clear);
return area;
}
}
/// <summary>
/// Sample view demonstrating how to use above infrastructure to create cross paltform views.
/// If below code is put into Shared lib then it compiles fine on iOS and Android.
/// On iOS you get TextArea with UITextView inside
/// On Android you get TextArea with Android.Widgets.TextArea inside
/// </summary>
public class SampleView : QodenView
{
public TextArea TextArea;
public SampleView()
{
TextArea = Builder.TextArea().StyleTextArea();
//You can set properties on PlatformView
TextArea.PlatformView.Text = "Hello World";
TextArea.PlatformView.BackgroundColor = RGB.Clear.ToColor();
//or on wrapper
TextArea
.SetText("Hello World").AsView()
.SetBackgroundColor(RGB.Clear);
TextArea.AsView().RemoveFromSuperview();
this.AsView().AddSubview(TextArea);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment