public void TryFacebookBind( )
        {
            SetUIState(LoginState.Trying);

            // have our rock mobile user begin the facebook bind process
            RockMobileUser.Instance.BindFacebookAccount(delegate(string fromUri)
            {
                // it's ready, so create a webView that will take them to the FBLogin page
                WebLayout = new WebLayout(ScrollView.Frame);
                WebLayout.DeleteCacheAndCookies( );

                ScrollView.AddSubview(WebLayout.ContainerView);

                // set it totally transparent so we can fade it in
                //WebLayout.ContainerView.BackgroundColor = UIColor.Green;
                WebLayout.ContainerView.Layer.Opacity = 0.00f;
                //WebLayout.SetCancelButtonColor( ControlStylingConfig.TextField_PlaceholderTextColor );
                WebLayout.LayoutChanged(new CGRect(0, 0, ScrollView.Frame.Width, ScrollView.Frame.Height));

                View.SetNeedsLayout( );

                // do a nice fade-in
                SimpleAnimator_Float floatAnimator = new SimpleAnimator_Float(0.00f, 1.00f, .25f,
                                                                              delegate(float percent, object value)
                {
                    WebLayout.ContainerView.Layer.Opacity = (float)value;
                },
                                                                              delegate
                {
                    // once faded in, begin loading the page
                    WebLayout.ContainerView.Layer.Opacity = 1.00f;

                    WebLayout.LoadUrl(fromUri, delegate(WebLayout.Result result, string url)
                    {
                        BlockerView.Hide( );

                        // if fail/success comes in
                        if (result != WebLayout.Result.Cancel)
                        {
                            // see if it's a valid facebook response

                            // if an empty url was returned, it's NOT. Fail.
                            if (string.IsNullOrEmpty(url) == true)
                            {
                                WebLayout.ContainerView.RemoveFromSuperview( );
                                BindComplete(false);
                            }
                            // otherwise, try to parse the response and move forward
                            else if (RockMobileUser.Instance.HasFacebookResponse(url))
                            {
                                // it is, continue the bind process
                                BlockerView.Show();

                                WebLayout.ContainerView.RemoveFromSuperview( );
                                RockMobileUser.Instance.FacebookCredentialResult(url, BindComplete);

                                ProfileAnalytic.Instance.Trigger(ProfileAnalytic.Login, "Facebook");
                            }
                        }
                        else
                        {
                            // they pressed cancel, so simply cancel the attempt
                            WebLayout.ContainerView.RemoveFromSuperview( );
                            LoginComplete(System.Net.HttpStatusCode.ResetContent, "");
                        }
                    });
                });

                floatAnimator.Start( );
            });
        }
        public override void ViewDidLayoutSubviews( )
        {
            base.ViewDidLayoutSubviews( );

            nfloat headerHeight = 0;

            ScrollView.Bounds = View.Bounds;

            // see if there's a safe area due to this being a "notch" device
            nfloat safeAreaTopInset = 0;
            nfloat safeAreaBotInset = 0;

            // Make sure they're on iOS 11 before checking for insets. This is only needed for iPhone X anyways, which shipped with iOS 11.
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                safeAreaTopInset = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets.Top;
                safeAreaBotInset = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets.Bottom;
            }

            // if there's no top safe area, there WILL be a header, so adjust for it.
            if (safeAreaTopInset == 0)
            {
                HeaderView.Frame = new CGRect(View.Frame.Left, 0, View.Frame.Width, StyledTextField.StyledFieldHeight);

                // setup the header shadow
                UIBezierPath shadowPath = UIBezierPath.FromRect(HeaderView.Bounds);
                HeaderView.Layer.MasksToBounds = false;
                HeaderView.Layer.ShadowColor   = UIColor.Black.CGColor;
                HeaderView.Layer.ShadowOffset  = new CoreGraphics.CGSize(0.0f, .0f);
                HeaderView.Layer.ShadowOpacity = .23f;
                HeaderView.Layer.ShadowPath    = shadowPath.CGPath;

                // the logo may not exist if we're on a display with a notch
                if (LogoView != null)
                {
                    LogoView.Layer.Position = new CoreGraphics.CGPoint((HeaderView.Bounds.Width - LogoView.Bounds.Width) / 2, 0);
                }

                headerHeight = HeaderView.Bounds.Height;

                // only move down the scrollview if there's a header
                ScrollView.Frame = new CGRect(View.Frame.Left, HeaderView.Frame.Bottom, View.Frame.Right, View.Frame.Bottom - headerHeight);
            }
            else
            {
                // otherwise, there's a safe area, so no header. We should therefore adjust the scrollview to be at the top of the window.
                ScrollView.Frame = new CGRect(View.Frame.Left, View.Frame.Top + safeAreaTopInset, View.Frame.Right, View.Frame.Bottom - (safeAreaBotInset + safeAreaTopInset));
            }


            UserNameField.SetFrame(new CGRect(-10, View.Frame.Height * .10f, View.Frame.Width + 20, StyledTextField.StyledFieldHeight));
            PasswordField.SetFrame(new CGRect(UserNameField.Background.Frame.Left, UserNameField.Background.Frame.Bottom, View.Frame.Width + 20, StyledTextField.StyledFieldHeight));

            // use the facebook image's button width, as it looks good.
            nfloat buttonWidth = FBImageView.Bounds.Width;

            LoginButton.Frame = new CGRect((ScrollView.Bounds.Width - buttonWidth) / 2, PasswordField.Background.Frame.Bottom + 20, buttonWidth, ControlStyling.ButtonHeight);
            LoginResult.SetFrame(new CGRect(UserNameField.Background.Frame.Left, LoginButton.Frame.Bottom + 20, View.Frame.Width + 20, StyledTextField.StyledFieldHeight));

            AdditionalOptions.Frame = new CGRect((View.Bounds.Width - AdditionalOptions.Bounds.Width) / 2, LoginResult.Background.Frame.Bottom + 10, AdditionalOptions.Bounds.Width, ControlStyling.ButtonHeight);

            // setup the "Forgot account, Register or Facebook"
            ForgotPasswordButton.Frame = new CGRect((View.Bounds.Width - buttonWidth) / 2, AdditionalOptions.Frame.Bottom + 5, buttonWidth, ControlStyling.ButtonHeight);
            RegisterButton.Frame       = new CGRect((View.Bounds.Width - buttonWidth) / 2, ForgotPasswordButton.Frame.Bottom + 15, buttonWidth, ControlStyling.ButtonHeight);
            OrSpacerLabel.Frame        = new CGRect((View.Bounds.Width - OrSpacerLabel.Bounds.Width) / 2, RegisterButton.Frame.Bottom + 5, OrSpacerLabel.Bounds.Width, FBImageView.Bounds.Height);
            FacebookLogin.Frame        = new CGRect((View.Bounds.Width - FBImageView.Bounds.Width) / 2, OrSpacerLabel.Frame.Bottom + 5, FBImageView.Bounds.Width, FBImageView.Bounds.Height);
            //

            CancelButton.Frame = new CGRect((View.Frame.Width - CancelButton.Frame.Width) / 2, FacebookLogin.Frame.Bottom + 20, CancelButton.Frame.Width, CancelButton.Frame.Height);

            FBImageView.Layer.Position = new CoreGraphics.CGPoint(FacebookLogin.Bounds.Width / 2, FacebookLogin.Bounds.Height / 2);

            if (WebLayout != null)
            {
                WebLayout.LayoutChanged(new CGRect(0, 0, ScrollView.Frame.Width, ScrollView.Frame.Height));
            }

            BlockerView.SetBounds(View.Frame.ToRectF( ));

            ScrollView.ContentSize = new CGSize(View.Bounds.Width, Math.Max(ScrollView.Bounds.Height * 1.02f, CancelButton.Frame.Bottom + 20 + headerHeight));
        }