summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs')
-rw-r--r--Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs298
1 files changed, 298 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs b/Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs
new file mode 100644
index 00000000..47ce0714
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/ContextScrollViewDelegate.cs
@@ -0,0 +1,298 @@
+´╗┐using System;
+using System.Drawing;
+using System.Collections.Generic;
+#if __UNIFIED__
+using UIKit;
+using Foundation;
+#else
+using MonoTouch.UIKit;
+using MonoTouch.Foundation;
+#endif
+#if __UNIFIED__
+using NSAction = System.Action;
+using RectangleF = CoreGraphics.CGRect;
+using SizeF = CoreGraphics.CGSize;
+using PointF = CoreGraphics.CGPoint;
+
+#else
+using nfloat=System.Single;
+using nint=System.Int32;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ internal class iOS7ButtonContainer : UIView
+ {
+ readonly nfloat _buttonWidth;
+
+ public iOS7ButtonContainer(nfloat buttonWidth) : base(new RectangleF(0, 0, 0, 0))
+ {
+ _buttonWidth = buttonWidth;
+ ClipsToBounds = true;
+ }
+
+ public override void LayoutSubviews()
+ {
+ var width = Frame.Width;
+ nfloat takenSpace = 0;
+
+ for (var i = 0; i < Subviews.Length; i++)
+ {
+ var view = Subviews[i];
+
+ var pos = Subviews.Length - i;
+ var x = width - _buttonWidth * pos;
+ view.Frame = new RectangleF(x, 0, view.Frame.Width, view.Frame.Height);
+
+ takenSpace += view.Frame.Width;
+ }
+ }
+ }
+
+ internal class ContextScrollViewDelegate : UIScrollViewDelegate
+ {
+ readonly nfloat _finalButtonSize;
+ UIView _backgroundView;
+ List<UIButton> _buttons;
+ UITapGestureRecognizer _closer;
+ UIView _container;
+ GlobalCloseContextGestureRecognizer _globalCloser;
+
+ bool _isDisposed;
+
+ UITableView _table;
+
+ public ContextScrollViewDelegate(UIView container, List<UIButton> buttons, bool isOpen)
+ {
+ IsOpen = isOpen;
+ _container = container;
+ _buttons = buttons;
+
+ for (var i = 0; i < buttons.Count; i++)
+ {
+ var b = buttons[i];
+ b.Hidden = !isOpen;
+
+ ButtonsWidth += b.Frame.Width;
+ _finalButtonSize = b.Frame.Width;
+ }
+ }
+
+ public nfloat ButtonsWidth { get; }
+
+ public Action ClosedCallback { get; set; }
+
+ public bool IsOpen { get; private set; }
+
+ public override void DraggingStarted(UIScrollView scrollView)
+ {
+ if (!IsOpen)
+ SetButtonsShowing(true);
+
+ var cell = GetContextCell(scrollView);
+ if (!cell.Selected)
+ return;
+
+ if (!IsOpen)
+ RemoveHighlight(scrollView);
+ }
+
+ public void PrepareForDeselect(UIScrollView scrollView)
+ {
+ RestoreHighlight(scrollView);
+ }
+
+ public override void Scrolled(UIScrollView scrollView)
+ {
+ var width = _finalButtonSize;
+ var count = _buttons.Count;
+
+ if (!UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
+ _container.Frame = new RectangleF(scrollView.Frame.Width, 0, scrollView.ContentOffset.X, scrollView.Frame.Height);
+ else
+ {
+ var ioffset = scrollView.ContentOffset.X / (float)count;
+
+ if (ioffset > width)
+ width = ioffset + 1;
+
+ for (var i = count - 1; i >= 0; i--)
+ {
+ var b = _buttons[i];
+ var rect = b.Frame;
+ b.Frame = new RectangleF(scrollView.Frame.Width + (count - (i + 1)) * ioffset, 0, width, rect.Height);
+ }
+ }
+
+ if (scrollView.ContentOffset.X == 0)
+ {
+ IsOpen = false;
+ SetButtonsShowing(false);
+ RestoreHighlight(scrollView);
+
+ ClearCloserRecognizer(scrollView);
+
+ if (ClosedCallback != null)
+ ClosedCallback();
+ }
+ }
+
+ public void Unhook(UIScrollView scrollView)
+ {
+ RestoreHighlight(scrollView);
+ ClearCloserRecognizer(scrollView);
+ }
+
+ public override void WillEndDragging(UIScrollView scrollView, PointF velocity, ref PointF targetContentOffset)
+ {
+ var width = ButtonsWidth;
+ var x = targetContentOffset.X;
+ var parentThreshold = scrollView.Frame.Width * .4f;
+ var contentThreshold = width * .8f;
+
+ if (x >= parentThreshold || x >= contentThreshold)
+ {
+ IsOpen = true;
+ targetContentOffset = new PointF(width, 0);
+ RemoveHighlight(scrollView);
+
+ if (_globalCloser == null)
+ {
+ UIView view = scrollView;
+ while (view.Superview != null)
+ {
+ view = view.Superview;
+
+ NSAction close = () =>
+ {
+ if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
+ RestoreHighlight(scrollView);
+
+ IsOpen = false;
+ scrollView.SetContentOffset(new PointF(0, 0), true);
+
+ ClearCloserRecognizer(scrollView);
+ };
+
+ var table = view as UITableView;
+ if (table != null)
+ {
+ _table = table;
+ _globalCloser = new GlobalCloseContextGestureRecognizer(scrollView, _buttons, close);
+ _globalCloser.ShouldRecognizeSimultaneously = (recognizer, r) => r == _table.PanGestureRecognizer;
+ table.AddGestureRecognizer(_globalCloser);
+
+ _closer = new UITapGestureRecognizer(close);
+ var cell = GetContextCell(scrollView);
+ cell.ContentCell.AddGestureRecognizer(_closer);
+ }
+ }
+ }
+ }
+ else
+ {
+ ClearCloserRecognizer(scrollView);
+
+ IsOpen = false;
+ targetContentOffset = new PointF(0, 0);
+
+ if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
+ RestoreHighlight(scrollView);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (_isDisposed)
+ return;
+
+ _isDisposed = true;
+
+ if (disposing)
+ {
+ ClosedCallback = null;
+
+ _table = null;
+ _backgroundView = null;
+ _container = null;
+
+ _buttons = null;
+ }
+
+ base.Dispose(disposing);
+ }
+
+ void ClearCloserRecognizer(UIScrollView scrollView)
+ {
+ if (_globalCloser == null)
+ return;
+
+ var cell = GetContextCell(scrollView);
+ cell.ContentCell.RemoveGestureRecognizer(_closer);
+ _closer.Dispose();
+ _closer = null;
+
+ _table.RemoveGestureRecognizer(_globalCloser);
+ _table = null;
+ _globalCloser.Dispose();
+ _globalCloser = null;
+ }
+
+ ContextActionsCell GetContextCell(UIScrollView scrollView)
+ {
+ var view = scrollView.Superview.Superview;
+ var cell = view as ContextActionsCell;
+ while (view.Superview != null)
+ {
+ cell = view as ContextActionsCell;
+ if (cell != null)
+ break;
+
+ view = view.Superview;
+ }
+
+ return cell;
+ }
+
+ void RemoveHighlight(UIScrollView scrollView)
+ {
+ var subviews = scrollView.Superview.Superview.Subviews;
+
+ var count = 0;
+ for (var i = 0; i < subviews.Length; i++)
+ {
+ var s = subviews[i];
+ if (s.Frame.Height > 1)
+ count++;
+ }
+
+ if (count <= 1)
+ return;
+
+ _backgroundView = subviews[0];
+ _backgroundView.RemoveFromSuperview();
+
+ var cell = GetContextCell(scrollView);
+ cell.SelectionStyle = UITableViewCellSelectionStyle.None;
+ }
+
+ void RestoreHighlight(UIScrollView scrollView)
+ {
+ if (_backgroundView == null)
+ return;
+
+ var cell = GetContextCell(scrollView);
+ cell.SelectionStyle = UITableViewCellSelectionStyle.Default;
+ cell.SetSelected(true, false);
+
+ scrollView.Superview.Superview.InsertSubview(_backgroundView, 0);
+ _backgroundView = null;
+ }
+
+ void SetButtonsShowing(bool show)
+ {
+ for (var i = 0; i < _buttons.Count; i++)
+ _buttons[i].Hidden = !show;
+ }
+ }
+} \ No newline at end of file