diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.iOS/Extensions | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Extensions')
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 |