Esempio n. 1
0
        public void SetFrameWithArrowDirection(CGRect frame, UIPopoverArrowDirection direction)
        {
            Frame            = frame;
            Layer.ShadowPath = TrianglePath(frame, direction, true).CGPath;
            Layer.ShadowPath = TrianglePath(frame, direction, false).CGPath;

            bool   leftOrRight = (direction == UIPopoverArrowDirection.Left || direction == UIPopoverArrowDirection.Right);
            CGRect pathRect    = new CGRect(CGPoint.Empty,
                                            new CGSize(frame.Width + (leftOrRight ? ShadowRadius + 1.0f : 2.0f * (ShadowRadius + 1.0f)),
                                                       frame.Height + (leftOrRight ? 2.0f * (ShadowRadius + 1.0f) : ShadowRadius + 1.0f)));

            if (direction == UIPopoverArrowDirection.Up)
            {
                pathRect.Y -= ShadowRadius + 1.0f;
            }
            else if (direction == UIPopoverArrowDirection.Left)
            {
                pathRect.X -= ShadowRadius + 1.0f;
            }

            UIBezierPath path = UIBezierPath.FromRect(pathRect);

            CAShapeLayer mask = new CAShapeLayer();

            mask.Path      = path.CGPath;
            mask.FillColor = UIColor.Black.CGColor;

            Layer.Mask            = mask;
            Layer.ShadowColor     = UIColor.Black.CGColor;
            Layer.ShadowOffset    = CGSize.Empty;
            Layer.ShadowRadius    = ShadowRadius;
            Layer.ShadowOpacity   = ShadowOpacity;
            Layer.ContentsScale   = UIScreen.MainScreen.Scale;
            Layer.BackgroundColor = UIColor.White.CGColor;
        }
Esempio n. 2
0
        private static Task <DropDownListSelection <T> > ShowInternal <T>(
            UIView containerView,
            object anchorUIElement,
            UITableViewCellStyle itemStyle,
            UITableViewStyle viewStyle,
            IEnumerable <T> items,
            Func <T, GenericCellDescriptor> itemDescriber,
            string dropDownTitle,
            UIPopoverArrowDirection arrowDirection,
            CGSize?fitSize
            )
        {
            if (itemDescriber == null)
            {
                throw new ArgumentNullException("displayNameGetter");
            }

            return(ShowInternal(
                       containerView,
                       anchorUIElement,
                       itemStyle,
                       viewStyle,
                       new [] { items },
                       (s) => new GenericTableViewSection <T>(dropDownTitle, items),
                       itemDescriber,
                       arrowDirection,
                       fitSize
                       ));
        }
		public PopoverRootElement(
			string caption, 
			string value, 
			Func<RootElement, UIViewController> createOnSelected, 
			UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirection.Any
		)
			: this(caption, value, createOnSelected, () => arrowDirection)
		{
		}
Esempio n. 4
0
        /// <summary>
        /// Shows the action sheet from a specific point.
        /// This method is only available on iPad devices.
        /// </summary>
        /// <param name="point">The point to show the action sheet from.An arrow will point towards this point.</param>
        /// <param name="view">The hosting view in which the action sheet should be shown.</param>
        /// <param name="arrowDirection">The direction in which the arrow should show and the side of the section at which the arrow should be placed.</param>
        /// <param name="animated">Whether the action sheet should show with an animation.</param>
        public void ShowFromPointInView(CGPoint point, UIView view, UIPopoverArrowDirection arrowDirection, bool animated)
        {
            if (_isVisible)
            {
                Console.WriteLine("********** Action Sheet is already visible.");
                return;
            }

            if (!_isiPad)
            {
                ShowInView(view, animated);
            }

            UIApplication.SharedApplication.BeginIgnoringInteractionEvents();

            _targetView = view;

            MoveToPoint(point, arrowDirection, false);

            if (_delegate != null)
            {
                _delegate.ActionSheetWillPresent(this);
            }

            NSNotificationCenter.DefaultCenter.AddObserver(new NSString("UIDeviceOrientationDidChangeNotification"), OrientationChanged);

            LayoutForVisible(!animated);

            _targetView.AddSubview(this);

            if (!animated)
            {
                UIApplication.SharedApplication.EndIgnoringInteractionEvents();
                if (_delegate != null)
                {
                    _delegate.ActionSheetDidPresent(this);
                }
            }
            else
            {
                float duration = 0.3f;
                Animate(duration,
                        () =>
                {
                    LayoutForVisible(true);
                },
                        () =>
                {
                    UIApplication.SharedApplication.EndIgnoringInteractionEvents();
                    if (_delegate != null)
                    {
                        _delegate.ActionSheetDidPresent(this);
                    }
                });
            }
        }
Esempio n. 5
0
        private void Changes(CGPoint point, UIPopoverArrowDirection arrowDirection)
        {
            Frame = _targetView.Bounds;
            CGRect finalFrame  = CGRect.Empty;
            float  arrowHeight = ArrowHeight;
            float  spacing     = Spacing;

            if (arrowDirection == UIPopoverArrowDirection.Right)
            {
                finalFrame.Width  = point.X - arrowHeight;
                finalFrame.Height = _targetView.Bounds.Height;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Left)
            {
                finalFrame.Width  = _targetView.Bounds.Width - point.X - arrowHeight;
                finalFrame.Height = _targetView.Bounds.Height;
                finalFrame.X      = point.X + arrowHeight;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Up)
            {
                finalFrame.Width  = _targetView.Bounds.Width;
                finalFrame.Height = _targetView.Bounds.Height - point.Y - arrowHeight;
                finalFrame.Y      = point.Y + arrowHeight;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Down)
            {
                finalFrame.Width  = _targetView.Bounds.Width;
                finalFrame.Height = point.Y - arrowHeight;
            }
            else
            {
                throw new ArgumentException("********** Invalid arrow direction.");
            }

            finalFrame.X      += spacing;
            finalFrame.Y      += spacing;
            finalFrame.Height -= spacing * 2.0f;
            finalFrame.Width  -= spacing * 2.0f;

            base.Draw(AlignmentRectInsets.InsetRect(finalFrame));

            _scrollViewHost.BackgroundColor = UIColor.White;

            _scrollViewHost.Layer.CornerRadius = HostsCornerRadius;

            _scrollViewHost.Layer.ShadowColor   = UIColor.Black.CGColor;
            _scrollViewHost.Layer.ShadowOffset  = CGSize.Empty;
            _scrollViewHost.Layer.ShadowRadius  = ShadowRadius;
            _scrollViewHost.Layer.ShadowOpacity = ShadowOpacity;

            LayoutSheetForFrame(finalFrame, false, true, true);
            AnchorSheetAtPoint(point, arrowDirection, finalFrame);
        }
Esempio n. 6
0
 public static Task <DropDownListSelection <TItem> > Show <TSection, TItem>(
     UIBarButtonItem barButton,
     UITableViewCellStyle itemStyle,
     IEnumerable <TSection> sections,
     Func <TSection, GenericTableViewSection <TItem> > sectionDescriber,
     Func <TItem, GenericCellDescriptor> itemDescriber,
     UITableViewStyle headerStyle           = UITableViewStyle.Plain,
     UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirection.Up,
     CGSize?fitSize = null
     ) where TSection : IEnumerable <TItem>
 {
     return(ShowInternal(null, barButton, itemStyle, headerStyle, sections, sectionDescriber, itemDescriber, arrowDirection, fitSize));
 }
Esempio n. 7
0
 public static Task <DropDownListSelection <T> > Show <T>(
     UIBarButtonItem barButton,
     UITableViewCellStyle itemStyle,
     IEnumerable <T> items,
     Func <T, GenericCellDescriptor> itemDescriber,
     string dropDownTitle                   = null,
     UITableViewStyle headerStyle           = UITableViewStyle.Plain,
     UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirection.Up,
     CGSize?fitSize = null
     )
 {
     return(ShowInternal(null, barButton, itemStyle, headerStyle, items, itemDescriber, dropDownTitle, arrowDirection, fitSize));
 }
Esempio n. 8
0
		public static void PresentFromRect(RectangleF rect, UIView inView, UIPopoverArrowDirection arrowDirection)
		{
			if(_Popover.ShouldDismiss == null) {
				_Popover.ShouldDismiss += (controller) => { return true; };
			}
			
			if(_Popover.DidDismiss == null) {
				_Popover.DidDismiss += (controller) => { Console.WriteLine("Popover Did Dismiss"); };
			}
			
			using(var pool = new NSAutoreleasePool()) {
			pool.BeginInvokeOnMainThread(()=> {
					_Popover.PresentPopover(rect, inView, arrowDirection, true);
				});
			}
		}
		public PopoverContainerView(SizeF size, RectangleF anchor, RectangleF displayArea, UIPopoverArrowDirection arrowDirection, PopoverContainerModel properties)
			: base()
		{
			Properties = properties;
			
			_CorrectedSize = new SizeF(size.Width + properties.LeftBgMargin + properties.RightBgMargin + properties.LeftContentMargin + properties.RightContentMargin,
				size.Height + properties.TopBgMargin + properties.BottomBgMargin + properties.TopContentMargin + properties.BottomContentMargin);
			
			DetermineGeometry(size, anchor, displayArea, arrowDirection);
			InitializeFrame();
			this.BackgroundColor = UIColor.Clear;
			
			var image = UIImage.FromBundle(properties.BackgroundImage);
			this._BackgroundImage = image.StretchableImage(properties.LeftBgCapSize, properties.TopBgCapSize);
			
			this.ClipsToBounds = true;
			this.UserInteractionEnabled = true;
		}
Esempio n. 10
0
        /// <summary>
        /// Moves the action sheet to a new point.
        /// This method can only be called if the action sheet is already visible on screen.
        /// This method is only available on iPad devices.
        /// </summary>
        /// <param name="point">The point to show the action sheet from. An arrow will point towards this point.</param>
        /// <param name="arrowDirection">The direction in which the arrow should show and the side of the section at which the arrow should be placed.</param>
        /// <param name="animated">Whether the action sheet should change point with an animation. If you are invoking this method from the animated interface orientation change methods of UIViewController (@c willAnimateRotationToInterfaceOrientation:) pass @c NO because the UIViewController will itself do the animation.</param>
        public void MoveToPoint(CGPoint point, UIPopoverArrowDirection arrowDirection, bool animated)
        {
            if (!_isiPad)
            {
                return;
            }

            if (!_isVisible)
            {
                Console.WriteLine("********** Action Sheet must be visible in order to move the anchor point");
                return;
            }

            UIApplication.SharedApplication.BeginIgnoringInteractionEvents();

            DisableCustomEasing = true;

            if (animated)
            {
                Animate(0.3,
                        () =>
                {
                    Changes(point, arrowDirection);
                },
                        () =>
                {
                    UIApplication.SharedApplication.EndIgnoringInteractionEvents();
                });
            }
            else
            {
                Changes(point, arrowDirection);
                UIApplication.SharedApplication.EndIgnoringInteractionEvents();
            }

            DisableCustomEasing = false;
        }
Esempio n. 11
0
        //NOTE Why do we need this?
        //public static Type LayerType { get { return typeof(CustomActionSheetLayer); } }

        UIBezierPath TrianglePath(CGRect rect, UIPopoverArrowDirection arrowDirection, bool closePath)
        {
            UIBezierPath path = new UIBezierPath();

            if (arrowDirection == UIPopoverArrowDirection.Down)
            {
                path.MoveTo(CGPoint.Empty);
                path.AddLineTo(new CGPoint(rect.Width / 2.0f, rect.Height));
                path.AddLineTo(new CGPoint(rect.Width, 0.0f));
            }
            else if (arrowDirection == UIPopoverArrowDirection.Left)
            {
                path.MoveTo(new CGPoint(rect.Width, 0.0f));
                path.AddLineTo(new CGPoint(0.0f, rect.Height / 2.0f));
                path.AddLineTo(new CGPoint(rect.Width, rect.Height));
            }
            else if (arrowDirection == UIPopoverArrowDirection.Right)
            {
                path.MoveTo(CGPoint.Empty);
                path.AddLineTo(new CGPoint(rect.Width, rect.Height / 2.0f));
                path.AddLineTo(new CGPoint(0.0f, rect.Height));
            }
            else if (arrowDirection == UIPopoverArrowDirection.Up)
            {
                path.MoveTo(new CGPoint(0.0f, rect.Height));
                path.AddLineTo(new CGPoint(rect.Width / 2.0f, 0.0f));
                path.AddLineTo(new CGPoint(rect.Width, rect.Height));
            }

            if (closePath)
            {
                path.ClosePath();
            }

            return(path);
        }
Esempio n. 12
0
 public void PresentFromRect(CGRect rect, UIView view, UIPopoverArrowDirection arrowDirections, bool animated)
 {
     ObjC.MessageSend(Handle, "presentPopoverFromRect:inView:permittedArrowDirections:animated:", rect, view.Handle, (uint)arrowDirections, animated);
 }
Esempio n. 13
0
 public static void PresentFromRect(RectangleF rect, UIView view, UIPopoverArrowDirection arrowDirection, bool animated)
 {
     _PopoverController.PresentFromRect(rect, view, arrowDirection, animated);
 }
Esempio n. 14
0
 public static void PresentFromRect(CGRect rect, UIView view, UIPopoverArrowDirection arrowDirection, bool animated)
 {
     _PopoverController.PresentPopover(rect, view, arrowDirection, animated);
 }
Esempio n. 15
0
        private static async Task <DropDownListSelection <TItem> > ShowInternal <TSection, TItem>(
            UIView containerView,
            object anchorUIElement,
            UITableViewCellStyle itemStyle,
            UITableViewStyle headerStyle,
            IEnumerable <TSection> sections,
            Func <TSection, GenericTableViewSection <TItem> > sectionDescriber,
            Func <TItem, GenericCellDescriptor> itemDescriber,
            UIPopoverArrowDirection arrowDirection,
            CGSize?fitSize
            ) where TSection : IEnumerable <TItem>
        {
            if (anchorUIElement == null)
            {
                throw new ArgumentNullException("anchorView");
            }

            if (!(anchorUIElement is UIView || anchorUIElement is UIBarButtonItem))
            {
                throw new ArgumentOutOfRangeException("anchorView", "Must be a UIView or a UIBarButtonItem");
            }

            var sectionsArray = sections.Select(sectionDescriber).ToArray();


            if (sectionsArray.Count() == 1 && string.IsNullOrWhiteSpace(sectionsArray.First().Title))
            {
                headerStyle = UITableViewStyle.Plain;
            }

            var selectSignal = new ManualResetEventSlim();
            var table        = new UITableViewController(headerStyle);

            table.AutomaticallyAdjustsScrollViewInsets = false;
            var result            = new DropDownListSelection <TItem>();
            var popOverController = new UIPopoverController(table);

            var dropDownSource = new GenericTableViewSource <TItem>(
                table.TableView,
                itemStyle,
                sectionsArray,
                itemDescriber,
                (x) => {
                result.SelectedItem = x;
                popOverController.Dismiss(false);
                selectSignal.Set();
            }
                );

            popOverController.DidDismiss += (object sender, EventArgs e) => {
                if (!selectSignal.IsSet)
                {
                    selectSignal.Set();
                }
            };

            ((UITableView)table.View).Source = dropDownSource;

            // Calculate how wide the view should be by finding how
            if (fitSize == null)
            {
                // calculate the fit size
                var    tableView     = (UITableView)table.View;
                nfloat largestWidth  = 0.0f;
                var    sectionHeight = (headerStyle == UITableViewStyle.Plain ? (float)tableView.SectionHeaderHeight : Tools.iOSTool.DefaultGroupedTableViewHeaderHeight);
                nfloat totalHeight   = sectionHeight * sectionsArray.Count(s => !string.IsNullOrWhiteSpace(s.Title));
                foreach (var section in sectionsArray)
                {
                    foreach (var itemDescriptor in ((IEnumerable <TItem>)section.Items).WithDescriptions())
                    {
                        var index    = itemDescriptor.Index;
                        var item     = itemDescriptor.Description;
                        var cellSize = (CGSize)dropDownSource.GetCell(tableView, (NSIndexPath)(NSIndexPath.FromRowSection(index, 0))).SizeThatFits((CGSize)CGSize.Empty);
                        if (cellSize.Width > largestWidth)
                        {
                            largestWidth = cellSize.Width;
                        }
                        totalHeight += cellSize.Height;
                    }
                }

                fitSize = new CGSize(largestWidth + ItemPadding, totalHeight);
            }
            popOverController.SetPopoverContentSize(fitSize.Value, false);

            TypeSwitch.Do(
                anchorUIElement,
                TypeSwitch.Case <UIBarButtonItem>(bbi =>
                                                  popOverController.PresentFromBarButtonItem(
                                                      (UIBarButtonItem)anchorUIElement,
                                                      arrowDirection,
                                                      true
                                                      )
                                                  ),
                TypeSwitch.Case <UIView>(v =>
                                         popOverController.PresentFromRect(
                                             ((UIView)anchorUIElement).Frame,
                                             containerView,
                                             arrowDirection,
                                             true
                                             )
                                         ),
                TypeSwitch.Case <UITabBarItem>(tb => {
                var tabBar = containerView as UITabBar;
                if (tabBar == null)
                {
                    throw new ArgumentException("Container view must be an UITabBar when the anchor view is an UITabBarItem");
                }

                if (!tabBar.Items.Contains(tb))
                {
                    throw new ArgumentException("Container view UITabBar does not contain the anchor view UITabBarItem");
                }

                var index           = tabBar.Items.IndexOf(tb);
                var tabBarItemWidth = tabBar.Frame.Size.Width / tabBar.Items.Count();
                var rect            = new CGRect(tabBarItemWidth * index, 0f, tabBarItemWidth, tabBar.Frame.Height);

                popOverController.PresentFromRect(
                    rect,
                    tabBar,
                    arrowDirection,
                    true
                    );
            }),
                TypeSwitch.Default(() => { throw new NotSupportedException("anchorUIElement was {0}".FormatWith(anchorUIElement.GetType().Name)); })
                );

            await Task.Run(() => selectSignal.Wait());

            table.View.DisposeEx();
            table.TableView.DisposeEx();
            table.Dispose();
            popOverController.Dispose();

            return(result);
        }
		public void UpdatePositionWithAnchorRect(RectangleF anchorRect, RectangleF displayArea, UIPopoverArrowDirection arrowDirections)
		{
			DetermineGeometry(_CorrectedSize, anchorRect, displayArea, arrowDirections);
			InitializeFrame();
		}
		public void PresentPopover(RectangleF rect, UIView inView, UIPopoverArrowDirection arrowDirection, bool animated)
		{
			this.DismissPopover(false);
			
			if(this.ContentViewController.View != null) { 
				//obj-C selector calls [vc getView] which calls loadView
			}
			
			if(this.ContentSize == SizeF.Empty) {
				this.ContentSize = this.ContentViewController.ContentSizeForViewInPopover;	
			}
			
			var displayArea = CalculateDisplayArea(inView);
			var properties = this.Properties ?? DefaultContainerModel;
			var containerView = new PopoverContainerView(this.ContentSize, rect, displayArea, arrowDirection, properties);
			this.ArrowDirection = containerView.PopoverArrowDirection;
			
			var keyView = this.GetKeyView();
			
			BackgroundView = new TouchableView() { Frame = keyView.Bounds };
			BackgroundView.ContentMode = UIViewContentMode.ScaleToFill;
			BackgroundView.BackgroundColor = UIColor.Clear;
			BackgroundView.ViewWasTouched = this.ViewWasTouched;
			BackgroundView.AutoresizingMask = 
					UIViewAutoresizing.FlexibleLeftMargin |
					UIViewAutoresizing.FlexibleWidth |
					UIViewAutoresizing.FlexibleRightMargin |
					UIViewAutoresizing.FlexibleTopMargin |
					UIViewAutoresizing.FlexibleHeight |
					UIViewAutoresizing.FlexibleBottomMargin;
			
			
			keyView.AddSubview(BackgroundView);
			
			containerView.Frame = inView.ConvertRectFromView(containerView.Frame, BackgroundView);
			BackgroundView.AddSubview(containerView);
			
			containerView.SetContentView(ContentViewController.View);
			containerView.AutoresizingMask = UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin;
			
			this.View = containerView;
			this.UpdateBackgroundPassthroughViews();
			this.ContentViewController.ViewWillAppear(animated);
			
			this.View.BecomeFirstResponder();
			
			if(animated) {
				this.View.Alpha = 0.0f;
				
				UIView.BeginAnimations("FadeIn", IntPtr.Zero);
				UIView.SetAnimationDuration(FadeDuration);
				UIView.SetAnimationDelegate(this);
			    UIView.SetAnimationDidStopSelector(new MonoTouch.ObjCRuntime.Selector("animationDidStop:finished:context:"));

				this.View.Alpha = 1.0f;
				
				UIView.CommitAnimations();
			}
			else {
				IsPopoverVisible = true;
				this.ContentViewController.ViewDidAppear(animated);
			}
		}
		public void RepositionPopover(RectangleF rect, UIView inView, UIPopoverArrowDirection arrowDirection)
		{
			var displayArea = CalculateDisplayArea(View);
			var containerView = (PopoverContainerView)this.View;
			
			containerView.UpdatePositionWithAnchorRect(rect, displayArea, arrowDirection);
			containerView.Frame = inView.ConvertRectToView(containerView.Frame, this.BackgroundView);
			ArrowDirection = arrowDirection;
		}
Esempio n. 19
0
 public void PresentFromRect(CGRect rect, UIView view, UIPopoverArrowDirection arrowDirections, bool animated)
 {
     ObjC.MessageSend(Handle, Selector.GetHandle("presentPopoverFromRect:inView:permittedArrowDirections:animated:"), rect, view.Handle, (uint)arrowDirections, animated);
 }
Esempio n. 20
0
 public virtual void PresentPopoverFromBarButtonItem(UIBarButtonItem item, UIPopoverArrowDirection permittedArrowDirections, bool animated)
 {
 }
Esempio n. 21
0
 public virtual void PresentPopoverFromRect(CGRect rect, UIView inView, UIPopoverArrowDirection permittedArrowDirections, bool animated)
 {
 }
Esempio n. 22
0
        private void AnchorSheetAtPoint(CGPoint point, UIPopoverArrowDirection arrowDirection, CGRect frame)
        {
            _anchoredAtPoint        = true;
            _anchorPoint            = point;
            _anchoredArrowDirection = arrowDirection;
            CGRect finalFrame = _scrollViewHost.Frame;

            float arrowHeight     = ArrowHeight;
            float arrrowBaseWidth = ArrowBaseWidth;

            bool leftOrRight = (arrowDirection == UIPopoverArrowDirection.Left || arrowDirection == UIPopoverArrowDirection.Right);

            CGRect arrowFrame = new CGRect(CGPoint.Empty, new CGSize((leftOrRight ? arrowHeight : arrrowBaseWidth), (leftOrRight ? arrrowBaseWidth : arrowHeight)));

            if (arrowDirection == UIPopoverArrowDirection.Right)
            {
                arrowFrame.X = point.X - arrowHeight;
                arrowFrame.Y = point.Y - arrrowBaseWidth / 2.0f;
                finalFrame.X = point.X - finalFrame.Width - arrowHeight;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Left)
            {
                arrowFrame.X = point.X;
                arrowFrame.Y = point.Y - arrrowBaseWidth / 2.0f;

                finalFrame.X = point.X + arrowHeight;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Up)
            {
                arrowFrame.X = point.X - arrrowBaseWidth / 2.0f;
                arrowFrame.Y = point.Y;

                finalFrame.Y = point.Y + arrowHeight;
            }
            else if (arrowDirection == UIPopoverArrowDirection.Down)
            {
                arrowFrame.X = point.X - arrrowBaseWidth / 2.0f;
                arrowFrame.Y = point.Y - arrowHeight;

                finalFrame.Y = point.Y - finalFrame.Height - arrowHeight;
            }

            if (leftOrRight)
            {
                finalFrame.Y = NMath.Min(NMath.Max(frame.GetMaxY() - finalFrame.Height, arrowFrame.GetMaxY() - finalFrame.Height + HostsCornerRadius),
                                         NMath.Min(NMath.Max(frame.GetMinY(), point.Y - finalFrame.Height / 2.0f), arrowFrame.GetMinY() - HostsCornerRadius));
            }
            else
            {
                finalFrame.X = NMath.Min(NMath.Max(NMath.Min(frame.GetMinX(), arrowFrame.GetMinX() - HostsCornerRadius), point.X - finalFrame.Width / 2.0f),
                                         NMath.Max(frame.GetMaxX() - finalFrame.Width, arrowFrame.GetMaxX() + HostsCornerRadius - finalFrame.Width));
            }

            if (_arrowView == null)
            {
                _arrowView = new CustomActionSheetTriangle();
                AddSubview(_arrowView);
            }

            _arrowView.SetFrameWithArrowDirection(arrowFrame, arrowDirection);

            if (!_targetView.Bounds.Contains(finalFrame) || !_targetView.Bounds.Contains(arrowFrame))
            {
                Console.WriteLine("WARNING: Action sheet does not fit within view bounds! Select a different arrow direction or provide a different anchor point.");
            }

            _scrollViewHost.Frame = finalFrame;
        }
		public void DetermineGeometry(SizeF size, RectangleF anchorRect, RectangleF displayArea, UIPopoverArrowDirection supportedDirections)
		{
			_Offset = PointF.Empty;
			_BackgroundRect = RectangleF.Empty;
			_ArrowRect = RectangleF.Empty;
			PopoverArrowDirection = UIPopoverArrowDirection.Unknown;
			
			var biggestSurface = 0.0f;
			var currentMinMargin = 0.0f;
			
			var upArrowImage = UIImage.FromBundle(this.Properties.UpArrowImage);
			var downArrowImage = UIImage.FromBundle(this.Properties.DownArrowImage);
			var leftArrowImage = UIImage.FromBundle(this.Properties.LeftArrowImage);
			var rightArrowImage = UIImage.FromBundle(this.Properties.RightArrowImage);
			
			foreach(var direction in (UIPopoverArrowDirection[])Enum.GetValues(typeof(UIPopoverArrowDirection))) {
				
				if(supportedDirections.HasFlag(direction)) {
					
					var bgRect = RectangleF.Empty;
					var arrowRect = RectangleF.Empty;
					var offset = PointF.Empty;
					var xArrowOffset = 0.0f;
					var yArrowOffset = 0.0f;
					var anchorPoint = PointF.Empty;
					
					switch(direction) {
						case UIPopoverArrowDirection.Up: {
							
							anchorPoint = new PointF(anchorRect.GetMidX(), anchorRect.GetMaxY());
							
							xArrowOffset = size.Width / 2 - upArrowImage.Size.Width / 2;
							yArrowOffset = Properties.TopBgMargin - upArrowImage.Size.Height;
							
							offset = new PointF(anchorPoint.X - xArrowOffset - upArrowImage.Size.Width / 2, anchorPoint.Y - yArrowOffset);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.X < 0) {
								xArrowOffset += offset.X;
								offset.X = 0;
							}
							else if(offset.X + size.Width > displayArea.Size.Width) {
								xArrowOffset += (offset.X + size.Width - displayArea.Size.Width);
								offset.X = displayArea.Size.Width - size.Width;
							}
						
							xArrowOffset = Math.Max(xArrowOffset, Properties.LeftBgMargin + Properties.ArrowMargin);
							xArrowOffset = Math.Min(xArrowOffset, size.Width - Properties.RightBgMargin - Properties.ArrowMargin - upArrowImage.Size.Width);
							
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, upArrowImage.Size.Width, upArrowImage.Size.Height);
						
							break;
						}
						case UIPopoverArrowDirection.Down: {
							anchorPoint = new PointF(anchorRect.GetMidX(), anchorRect.GetMinY());
						
							xArrowOffset = size.Width / 2 - downArrowImage.Size.Width / 2;
							yArrowOffset = size.Height - Properties.BottomBgMargin;
						
							offset = new PointF(anchorPoint.X - xArrowOffset - downArrowImage.Size.Width / 2,
								anchorPoint.Y - yArrowOffset - downArrowImage.Size.Height);
						
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.X < 0) {
								xArrowOffset += offset.X;
								offset.X = 0;
							}
							else if(offset.X + size.Width > displayArea.Size.Width) {
								xArrowOffset += (offset.X + size.Width - displayArea.Size.Width);
								offset.X = displayArea.Size.Width - size.Width;
							}
						
							//cap arrow offset;
							xArrowOffset = Math.Max(xArrowOffset, Properties.LeftBgMargin + Properties.ArrowMargin);
							xArrowOffset = Math.Min(xArrowOffset, size.Width - Properties.RightBgMargin - Properties.ArrowMargin - downArrowImage.Size.Width);
							
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, downArrowImage.Size.Width, downArrowImage.Size.Height);
							
							break;
						}
						case UIPopoverArrowDirection.Left: {
							anchorPoint = new PointF(anchorRect.GetMaxX(), anchorRect.GetMidY());
						
							xArrowOffset = Properties.LeftBgMargin - leftArrowImage.Size.Width;
							yArrowOffset = size.Height / 2 - leftArrowImage.Size.Height / 2;
						
							offset = new PointF(anchorPoint.X - xArrowOffset, anchorPoint.Y - yArrowOffset - leftArrowImage.Size.Height / 2);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
							
							if(offset.Y < 0) {
								yArrowOffset += offset.Y;
								offset.Y = 0;
							}
							else if(offset.Y + size.Height > displayArea.Size.Height) {
								yArrowOffset += (offset.Y + size.Height) - displayArea.Size.Height;
								offset.Y = displayArea.Size.Height - size.Height;
							}
						
							//cap arrow offset;
							yArrowOffset = Math.Max(yArrowOffset, Properties.TopBgMargin + Properties.ArrowMargin);
							yArrowOffset = Math.Min(yArrowOffset, size.Height - Properties.BottomBgMargin - Properties.ArrowMargin - leftArrowImage.Size.Height);
						
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, leftArrowImage.Size.Width, leftArrowImage.Size.Height);
						
							break;	
						}
						case UIPopoverArrowDirection.Right: {
							anchorPoint = new PointF(anchorRect.GetMinX(), anchorRect.GetMidY());
							
							xArrowOffset = size.Width - Properties.RightBgMargin;
							yArrowOffset = size.Height / 2 - rightArrowImage.Size.Width / 2;
							
							offset = new PointF(anchorPoint.X - xArrowOffset - rightArrowImage.Size.Width, anchorPoint.Y - yArrowOffset - rightArrowImage.Size.Height / 2);
							bgRect = new RectangleF(0, 0, size.Width, size.Height);
						
							if(offset.Y < 0) {
								yArrowOffset += offset.Y;
								offset.Y = 0;
							}
							else if(offset.Y + size.Height > displayArea.Size.Height) {
								yArrowOffset += (offset.Y + size.Height) - displayArea.Size.Height;
								offset.Y = displayArea.Size.Height - size.Height;
							}
						
							//cap arrow offset;
							yArrowOffset = Math.Max(yArrowOffset, Properties.TopBgMargin + Properties.ArrowMargin);
							yArrowOffset = Math.Min(yArrowOffset, size.Height - Properties.BottomBgMargin - Properties.ArrowMargin - rightArrowImage.Size.Height);
						
							arrowRect = new RectangleF(xArrowOffset, yArrowOffset, rightArrowImage.Size.Width, rightArrowImage.Size.Height);
							
							break;	
						}
					}
					
					//end switch statement
					
//					var bgFrame = bgRect.RectOffset(offset.X, offset.Y);
//					var bgFrame = RectangleFExtensions.Offset(bgRect, offset.X, offset.Y);
					var bgFrame = bgRect;
					bgFrame.X += offset.X;
					bgFrame.Y += offset.Y;
					
					var minMarginLeft = bgFrame.GetMinX() - displayArea.GetMinX();
					var minMarginRight = displayArea.GetMaxX() - bgFrame.GetMaxY();
					var minMarginTop = bgFrame.GetMinY() - displayArea.GetMinY();
					var minMarginBottom = displayArea.GetMaxY() - bgFrame.GetMaxY();
					
					if(minMarginLeft < 0) {
					    // Popover is too wide and clipped on the left; decrease width
			    		// and move it to the right
						
						offset.X -= minMarginLeft;
						bgRect.Size.Width += minMarginLeft;
						minMarginLeft = 0;
						
						if(direction == UIPopoverArrowDirection.Right) {
							arrowRect.X = bgRect.GetMaxX() - Properties.RightBgMargin;
						}
					}
					
					if(minMarginRight < 0) {
						// Popover is too wide and clipped on the right; decrease width.
						
						bgRect.Size.Width += minMarginRight;
						minMarginRight = 0;
						
						if(direction == UIPopoverArrowDirection.Left) {
							arrowRect.X = bgRect.GetMinX() - leftArrowImage.Size.Width + Properties.LeftBgMargin;	
						}
					}
					
					if(minMarginTop < 0) {
						// Popover is too high and clipped at the top; decrease height and move it down
						
						offset.Y -= minMarginTop;
						bgRect.Size.Height += minMarginTop;
						minMarginTop = 0;
						
						if(direction == UIPopoverArrowDirection.Down) {
							arrowRect.Y = bgRect.GetMaxY() - Properties.BottomBgMargin;	
						}
					}

					if(minMarginBottom < 0) {
						// Popover is too high and clipped at the bottom; decrease height.
						
						bgRect.Size.Height += minMarginBottom;
						minMarginBottom = 0;
						
						if(direction == UIPopoverArrowDirection.Up) {
							arrowRect.Y = bgRect.GetMinY() - upArrowImage.Size.Height + Properties.TopBgMargin;	
						}
					}
					
					bgFrame = bgRect.RectOffset(offset.X, offset.Y);
					
					var minMargin = Math.Min(minMarginLeft, minMarginRight);
					minMargin = Math.Min(minMargin, minMarginTop);
					minMargin = Math.Min(minMargin, minMarginBottom);
					
					// Calculate intersection and surface
					var intersection = RectangleF.Intersect(displayArea, bgFrame);
					var surface = intersection.Size.Width * intersection.Size.Height;
					
					if(surface >= biggestSurface && minMargin >= currentMinMargin) {
						
						biggestSurface = surface;
						_Offset = offset;
						_ArrowRect = arrowRect;
						_BackgroundRect = bgRect;
						PopoverArrowDirection = direction;
						currentMinMargin = minMargin;
					}
				} // end if
			} //end foreach
			
			switch(PopoverArrowDirection) {
				case UIPopoverArrowDirection.Up:
					_ArrowImage = upArrowImage;
					break;
				case UIPopoverArrowDirection.Down:
					_ArrowImage = downArrowImage;
					break;
				case UIPopoverArrowDirection.Left:
					_ArrowImage = leftArrowImage;
					break;
				case UIPopoverArrowDirection.Right:
					_ArrowImage = rightArrowImage;
					break;
			}
		}