summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/Extensions
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Extensions')
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/ArrayExtensions.cs38
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/CellExtensions.cs41
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/ColorExtensions.cs99
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/DateExtensions.cs33
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/Extensions.cs76
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/ToolbarItemExtensions.cs228
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/UIViewExtensions.cs66
-rw-r--r--Xamarin.Forms.Platform.iOS/Extensions/ViewExtensions.cs20
8 files changed, 601 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/ArrayExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/ArrayExtensions.cs
new file mode 100644
index 00000000..9adafecb
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/ArrayExtensions.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ internal static class ArrayExtensions
+ {
+ public static T[] Insert<T>(this T[] self, int index, T item)
+ {
+ var result = new T[self.Length + 1];
+ if (index > 0)
+ Array.Copy(self, result, index);
+
+ result[index] = item;
+
+ if (index < self.Length)
+ Array.Copy(self, index, result, index + 1, result.Length - index - 1);
+
+ return result;
+ }
+
+ public static T[] Remove<T>(this T[] self, T item)
+ {
+ return self.RemoveAt(self.IndexOf(item));
+ }
+
+ public static T[] RemoveAt<T>(this T[] self, int index)
+ {
+ var result = new T[self.Length - 1];
+ if (index > 0)
+ Array.Copy(self, result, index);
+
+ if (index < self.Length - 1)
+ Array.Copy(self, index + 1, result, index, self.Length - index - 1);
+
+ return result;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/CellExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/CellExtensions.cs
new file mode 100644
index 00000000..ca05bc54
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/CellExtensions.cs
@@ -0,0 +1,41 @@
+using System;
+#if __UNIFIED__
+using Foundation;
+
+#else
+using MonoTouch.Foundation;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ internal static class CellExtensions
+ {
+ internal static NSIndexPath GetIndexPath(this Cell self)
+ {
+ if (self == null)
+ throw new ArgumentNullException("self");
+
+ NSIndexPath path;
+
+ if (self.RealParent is ListView)
+ {
+ var section = 0;
+ var til = TemplatedItemsList<ItemsView<Cell>, Cell>.GetGroup(self);
+ if (til != null)
+ section = TemplatedItemsList<ItemsView<Cell>, Cell>.GetIndex(til.HeaderContent);
+
+ var row = TemplatedItemsList<ItemsView<Cell>, Cell>.GetIndex(self);
+ path = NSIndexPath.FromRowSection(row, section);
+ }
+ else if (self.RealParent is TableView)
+ {
+ var tmPath = TableView.TableSectionModel.GetPath(self);
+ path = NSIndexPath.FromRowSection(tmPath.Item2, tmPath.Item1);
+ }
+ else
+ throw new NotSupportedException("Unknown cell parent type");
+
+ return path;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/ColorExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/ColorExtensions.cs
new file mode 100644
index 00000000..f512e157
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/ColorExtensions.cs
@@ -0,0 +1,99 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+#if __UNIFIED__
+using CoreAnimation;
+using CoreGraphics;
+using Foundation;
+using UIKit;
+#else
+using MonoTouch.CoreAnimation;
+using MonoTouch.CoreGraphics;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+#if __UNIFIED__
+using RectangleF = CoreGraphics.CGRect;
+using SizeF = CoreGraphics.CGSize;
+using PointF = CoreGraphics.CGPoint;
+
+#else
+using nfloat=System.Single;
+using nint=System.Int32;
+using nuint=System.UInt32;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class ColorExtensions
+ {
+ internal static readonly UIColor Black = UIColor.Black;
+ internal static readonly UIColor SeventyPercentGrey = new UIColor(0.7f, 0.7f, 0.7f, 1);
+
+ public static CGColor ToCGColor(this Color color)
+ {
+ return new CGColor((float)color.R, (float)color.G, (float)color.B, (float)color.A);
+ }
+
+ public static Color ToColor(this UIColor color)
+ {
+ nfloat red;
+ nfloat green;
+ nfloat blue;
+ nfloat alpha;
+ color.GetRGBA(out red, out green, out blue, out alpha);
+ return new Color(red, green, blue, alpha);
+ }
+
+ public static UIColor ToUIColor(this Color color)
+ {
+ return new UIColor((float)color.R, (float)color.G, (float)color.B, (float)color.A);
+ }
+
+ public static UIColor ToUIColor(this Color color, Color defaultColor)
+ {
+ if (color.IsDefault)
+ return defaultColor.ToUIColor();
+
+ return color.ToUIColor();
+ }
+
+ public static UIColor ToUIColor(this Color color, UIColor defaultColor)
+ {
+ if (color.IsDefault)
+ return defaultColor;
+
+ return color.ToUIColor();
+ }
+ }
+
+ public static class PointExtensions
+ {
+ public static Point ToPoint(this PointF point)
+ {
+ return new Point(point.X, point.Y);
+ }
+ }
+
+ public static class SizeExtensions
+ {
+ public static SizeF ToSizeF(this Size size)
+ {
+ return new SizeF((float)size.Width, (float)size.Height);
+ }
+ }
+
+ public static class RectangleExtensions
+ {
+ public static Rectangle ToRectangle(this RectangleF rect)
+ {
+ return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ public static RectangleF ToRectangleF(this Rectangle rect)
+ {
+ return new RectangleF((nfloat)rect.X, (nfloat)rect.Y, (nfloat)rect.Width, (nfloat)rect.Height);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/DateExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/DateExtensions.cs
new file mode 100644
index 00000000..a75e7a69
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/DateExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+#if __UNIFIED__
+using CoreAnimation;
+using CoreGraphics;
+using Foundation;
+using UIKit;
+
+#else
+using MonoTouch.CoreAnimation;
+using MonoTouch.CoreGraphics;
+using MonoTouch.Foundation;
+using MonoTouch.UIKit;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class DateExtensions
+ {
+ public static DateTime ToDateTime(this NSDate date)
+ {
+ return new DateTime(2001, 1, 1, 0, 0, 0).AddSeconds(date.SecondsSinceReferenceDate);
+ }
+
+ public static NSDate ToNSDate(this DateTime date)
+ {
+ return NSDate.FromTimeIntervalSinceReferenceDate((date - new DateTime(2001, 1, 1, 0, 0, 0)).TotalSeconds);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/Extensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/Extensions.cs
new file mode 100644
index 00000000..e74fed8d
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/Extensions.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+#if __UNIFIED__
+using UIKit;
+
+#else
+using MonoTouch.UIKit;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class Extensions
+ {
+ public static void ApplyKeyboard(this IUITextInput textInput, Keyboard keyboard)
+ {
+ textInput.AutocapitalizationType = UITextAutocapitalizationType.None;
+ textInput.AutocorrectionType = UITextAutocorrectionType.No;
+ textInput.SpellCheckingType = UITextSpellCheckingType.No;
+
+ if (keyboard == Keyboard.Default)
+ {
+ textInput.AutocapitalizationType = UITextAutocapitalizationType.Sentences;
+ textInput.AutocorrectionType = UITextAutocorrectionType.Default;
+ textInput.SpellCheckingType = UITextSpellCheckingType.Default;
+ textInput.KeyboardType = UIKeyboardType.Default;
+ }
+ else if (keyboard == Keyboard.Chat)
+ {
+ textInput.AutocapitalizationType = UITextAutocapitalizationType.Sentences;
+ textInput.AutocorrectionType = UITextAutocorrectionType.Yes;
+ }
+ else if (keyboard == Keyboard.Email)
+ textInput.KeyboardType = UIKeyboardType.EmailAddress;
+ else if (keyboard == Keyboard.Numeric)
+ textInput.KeyboardType = UIKeyboardType.DecimalPad;
+ else if (keyboard == Keyboard.Telephone)
+ textInput.KeyboardType = UIKeyboardType.PhonePad;
+ else if (keyboard == Keyboard.Text)
+ {
+ textInput.AutocapitalizationType = UITextAutocapitalizationType.Sentences;
+ textInput.AutocorrectionType = UITextAutocorrectionType.Yes;
+ textInput.SpellCheckingType = UITextSpellCheckingType.Yes;
+ }
+ else if (keyboard == Keyboard.Url)
+ textInput.KeyboardType = UIKeyboardType.Url;
+ else if (keyboard is CustomKeyboard)
+ {
+ var custom = (CustomKeyboard)keyboard;
+ var capitalizedSentenceEnabled = (custom.Flags & KeyboardFlags.CapitalizeSentence) == KeyboardFlags.CapitalizeSentence;
+ var spellcheckEnabled = (custom.Flags & KeyboardFlags.Spellcheck) == KeyboardFlags.Spellcheck;
+ var suggestionsEnabled = (custom.Flags & KeyboardFlags.Suggestions) == KeyboardFlags.Suggestions;
+
+ textInput.AutocapitalizationType = capitalizedSentenceEnabled ? UITextAutocapitalizationType.Sentences : UITextAutocapitalizationType.None;
+ textInput.AutocorrectionType = suggestionsEnabled ? UITextAutocorrectionType.Yes : UITextAutocorrectionType.No;
+ textInput.SpellCheckingType = spellcheckEnabled ? UITextSpellCheckingType.Yes : UITextSpellCheckingType.No;
+ }
+ }
+
+ internal static DeviceOrientation ToDeviceOrientation(this UIDeviceOrientation orientation)
+ {
+ switch (orientation)
+ {
+ case UIDeviceOrientation.Portrait:
+ return DeviceOrientation.Portrait;
+ case UIDeviceOrientation.PortraitUpsideDown:
+ return DeviceOrientation.PortraitDown;
+ case UIDeviceOrientation.LandscapeLeft:
+ return DeviceOrientation.LandscapeLeft;
+ case UIDeviceOrientation.LandscapeRight:
+ return DeviceOrientation.LandscapeRight;
+ default:
+ return DeviceOrientation.Other;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/ToolbarItemExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/ToolbarItemExtensions.cs
new file mode 100644
index 00000000..71bdbbac
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/ToolbarItemExtensions.cs
@@ -0,0 +1,228 @@
+using System;
+using System.Drawing;
+using System.ComponentModel;
+#if __UNIFIED__
+using CoreGraphics;
+using UIKit;
+#else
+using MonoTouch.CoreGraphics;
+using MonoTouch.UIKit;
+#endif
+#if __UNIFIED__
+using RectangleF = CoreGraphics.CGRect;
+using SizeF = CoreGraphics.CGSize;
+using PointF = CoreGraphics.CGPoint;
+
+#else
+using nfloat=System.Single;
+using nint=System.Int32;
+using nuint=System.UInt32;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class ToolbarItemExtensions
+ {
+ public static UIBarButtonItem ToUIBarButtonItem(this ToolbarItem item, bool forceName = false)
+ {
+ return item.Order == ToolbarItemOrder.Secondary ? new SecondaryToolbarItem(item) : (UIBarButtonItem)new PrimaryToolbarItem(item, forceName);
+ }
+
+ sealed class PrimaryToolbarItem : UIBarButtonItem
+ {
+ readonly bool _forceName;
+ readonly ToolbarItem _item;
+
+ public PrimaryToolbarItem(ToolbarItem item, bool forceName)
+ {
+ _forceName = forceName;
+ _item = item;
+
+ if (!string.IsNullOrEmpty(item.Icon) && !forceName)
+ UpdateIconAndStyle();
+ else
+ UpdateTextAndStyle();
+ UpdateIsEnabled();
+
+ Clicked += (sender, e) => item.Activate();
+ item.PropertyChanged += OnPropertyChanged;
+
+ if (item != null && !string.IsNullOrEmpty(item.AutomationId))
+ AccessibilityIdentifier = item.AutomationId;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ _item.PropertyChanged -= OnPropertyChanged;
+ base.Dispose(disposing);
+ }
+
+ void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == MenuItem.IsEnabledProperty.PropertyName)
+ UpdateIsEnabled();
+ else if (e.PropertyName == MenuItem.TextProperty.PropertyName)
+ {
+ if (string.IsNullOrEmpty(_item.Icon) || _forceName)
+ UpdateTextAndStyle();
+ }
+ else if (e.PropertyName == MenuItem.IconProperty.PropertyName)
+ {
+ if (!_forceName)
+ {
+ if (!string.IsNullOrEmpty(_item.Icon))
+ UpdateIconAndStyle();
+ else
+ UpdateTextAndStyle();
+ }
+ }
+ }
+
+ void UpdateIconAndStyle()
+ {
+ var image = UIImage.FromBundle(_item.Icon);
+ Image = image;
+ Style = UIBarButtonItemStyle.Plain;
+ }
+
+ void UpdateIsEnabled()
+ {
+ Enabled = _item.IsEnabled;
+ }
+
+ void UpdateTextAndStyle()
+ {
+ Title = _item.Text;
+ Style = UIBarButtonItemStyle.Bordered;
+ Image = null;
+ }
+ }
+
+ sealed class SecondaryToolbarItem : UIBarButtonItem
+ {
+ readonly ToolbarItem _item;
+
+ public SecondaryToolbarItem(ToolbarItem item) : base(new SecondaryToolbarItemContent())
+ {
+ _item = item;
+ UpdateText();
+ UpdateIcon();
+ UpdateIsEnabled();
+
+ ((SecondaryToolbarItemContent)CustomView).TouchUpInside += (sender, e) => item.Activate();
+ item.PropertyChanged += OnPropertyChanged;
+
+ if (item != null && !string.IsNullOrEmpty(item.AutomationId))
+ AccessibilityIdentifier = item.AutomationId;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ _item.PropertyChanged -= OnPropertyChanged;
+ base.Dispose(disposing);
+ }
+
+ void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == MenuItem.TextProperty.PropertyName)
+ UpdateText();
+ else if (e.PropertyName == MenuItem.IconProperty.PropertyName)
+ UpdateIcon();
+ else if (e.PropertyName == MenuItem.IsEnabledProperty.PropertyName)
+ UpdateIsEnabled();
+ }
+
+ void UpdateIcon()
+ {
+ ((SecondaryToolbarItemContent)CustomView).Image = string.IsNullOrEmpty(_item.Icon) ? null : new UIImage(_item.Icon);
+ }
+
+ void UpdateIsEnabled()
+ {
+ ((UIControl)CustomView).Enabled = _item.IsEnabled;
+ }
+
+ void UpdateText()
+ {
+ ((SecondaryToolbarItemContent)CustomView).Text = _item.Text;
+ }
+
+ sealed class SecondaryToolbarItemContent : UIControl
+ {
+ readonly UIImageView _imageView;
+ readonly UILabel _label;
+
+ public SecondaryToolbarItemContent() : base(new RectangleF(0, 0, 75, 20))
+ {
+ BackgroundColor = UIColor.Clear;
+ _imageView = new UIImageView { BackgroundColor = UIColor.Clear };
+ AddSubview(_imageView);
+
+ _label = new UILabel { BackgroundColor = UIColor.Clear, Lines = 1, LineBreakMode = UILineBreakMode.TailTruncation, Font = UIFont.SystemFontOfSize(10) };
+ AddSubview(_label);
+ }
+
+ public override bool Enabled
+ {
+ get { return base.Enabled; }
+ set
+ {
+ base.Enabled = value;
+ _label.Enabled = value;
+ _imageView.Alpha = value ? 1f : 0.25f;
+ }
+ }
+
+ public UIImage Image
+ {
+ get { return _imageView.Image; }
+ set { _imageView.Image = value; }
+ }
+
+ public string Text
+ {
+ get { return _label.Text; }
+ set { _label.Text = value; }
+ }
+
+ public override void LayoutSubviews()
+ {
+ base.LayoutSubviews();
+
+ const float padding = 5f;
+ var imageSize = _imageView.SizeThatFits(Bounds.Size);
+ var fullStringSize = _label.SizeThatFits(Bounds.Size);
+
+ if (imageSize.Width > 0 && (string.IsNullOrEmpty(Text) || fullStringSize.Width > Bounds.Width / 3))
+ {
+ _imageView.Frame = new RectangleF(PointF.Empty, imageSize);
+ _imageView.Center = new PointF(Bounds.GetMidX(), Bounds.GetMidY());
+ _label.Hidden = true;
+ return;
+ }
+
+ _label.Hidden = false;
+ var availableWidth = Bounds.Width - padding * 3 - imageSize.Width;
+ var stringSize = _label.SizeThatFits(new SizeF(availableWidth, Bounds.Height - padding * 2));
+
+ availableWidth = Bounds.Width;
+ availableWidth -= stringSize.Width;
+ availableWidth -= imageSize.Width;
+
+ var x = availableWidth / 2;
+
+ var frame = new RectangleF(new PointF(x, Bounds.GetMidY() - imageSize.Height / 2), imageSize);
+ _imageView.Frame = frame;
+
+ frame.X = frame.Right + (imageSize.Width > 0 ? padding : 0);
+ frame.Size = stringSize;
+ frame.Height = Bounds.Height;
+ frame.Y = 0;
+ _label.Frame = frame;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/UIViewExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/UIViewExtensions.cs
new file mode 100644
index 00000000..9847867c
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/UIViewExtensions.cs
@@ -0,0 +1,66 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System;
+#if __UNIFIED__
+using UIKit;
+
+#else
+using MonoTouch.UIKit;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class UIViewExtensions
+ {
+ public static IEnumerable<UIView> Descendants(this UIView self)
+ {
+ if (self.Subviews == null)
+ return Enumerable.Empty<UIView>();
+ return self.Subviews.Concat(self.Subviews.SelectMany(s => s.Descendants()));
+ }
+
+ public static SizeRequest GetSizeRequest(this UIView self, double widthConstraint, double heightConstraint, double minimumWidth = -1, double minimumHeight = -1)
+ {
+ var s = self.SizeThatFits(new SizeF((float)widthConstraint, (float)heightConstraint));
+ var request = new Size(s.Width == float.PositiveInfinity ? double.PositiveInfinity : s.Width, s.Height == float.PositiveInfinity ? double.PositiveInfinity : s.Height);
+ var minimum = new Size(minimumWidth < 0 ? request.Width : minimumWidth, minimumHeight < 0 ? request.Height : minimumHeight);
+ return new SizeRequest(request, minimum);
+ }
+
+ internal static T FindDescendantView<T>(this UIView view) where T : UIView
+ {
+ var queue = new Queue<UIView>();
+ queue.Enqueue(view);
+
+ while (queue.Count > 0)
+ {
+ var descendantView = queue.Dequeue();
+
+ var result = descendantView as T;
+ if (result != null)
+ return result;
+
+ for (var i = 0; i < descendantView.Subviews.Length; i++)
+ queue.Enqueue(descendantView.Subviews[i]);
+ }
+
+ return null;
+ }
+
+ internal static UIView FindFirstResponder(this UIView view)
+ {
+ if (view.IsFirstResponder)
+ return view;
+
+ foreach (var subView in view.Subviews)
+ {
+ var firstResponder = subView.FindFirstResponder();
+ if (firstResponder != null)
+ return firstResponder;
+ }
+
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Platform.iOS/Extensions/ViewExtensions.cs b/Xamarin.Forms.Platform.iOS/Extensions/ViewExtensions.cs
new file mode 100644
index 00000000..9ded0632
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Extensions/ViewExtensions.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ public static class ViewExtensions
+ {
+ public static IEnumerable<Page> GetParentPages(this Page target)
+ {
+ var result = new List<Page>();
+ var parent = target.RealParent as Page;
+ while (!Application.IsApplicationOrNull(parent))
+ {
+ result.Add(parent);
+ parent = parent.RealParent as Page;
+ }
+
+ return result;
+ }
+ }
+} \ No newline at end of file