Skip to content

Instantly share code, notes, and snippets.

@amay077
Created January 11, 2017 15:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amay077/30dda6f0db6132b9d71476f637646cbb to your computer and use it in GitHub Desktop.
Save amay077/30dda6f0db6132b9d71476f637646cbb to your computer and use it in GitHub Desktop.
using System;
using Xamarin.Forms.Platform.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;
using CoreGraphics;
using KeyboardOverlap.Forms.Plugin.iOSUnified;
using System.Diagnostics;
[assembly: ExportRenderer(typeof(Page), typeof(KeyboardOverlapRenderer))]
namespace KeyboardOverlap.Forms.Plugin.iOSUnified
{
[Preserve(AllMembers = true)]
public class KeyboardOverlapRenderer : PageRenderer
{
NSObject _keyboardShowObserver;
NSObject _keyboardHideObserver;
private bool _pageWasShiftedUp;
private double _activeViewBottom;
private bool _isKeyboardShown;
public static void Init()
{
var now = DateTime.Now;
Debug.WriteLine("Keyboard Overlap plugin initialized {0}", now);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var page = Element as ContentPage;
if (page != null)
{
var contentScrollView = page.Content as ScrollView;
if (contentScrollView != null)
return;
RegisterForKeyboardNotifications();
}
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
UnregisterForKeyboardNotifications();
}
void RegisterForKeyboardNotifications()
{
if (_keyboardShowObserver == null)
_keyboardShowObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardShow);
if (_keyboardHideObserver == null)
_keyboardHideObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardHide);
}
void UnregisterForKeyboardNotifications()
{
_isKeyboardShown = false;
if (_keyboardShowObserver != null)
{
NSNotificationCenter.DefaultCenter.RemoveObserver(_keyboardShowObserver);
_keyboardShowObserver.Dispose();
_keyboardShowObserver = null;
}
if (_keyboardHideObserver != null)
{
NSNotificationCenter.DefaultCenter.RemoveObserver(_keyboardHideObserver);
_keyboardHideObserver.Dispose();
_keyboardHideObserver = null;
}
}
protected virtual void OnKeyboardShow(NSNotification notification)
{
if (!IsViewLoaded || _isKeyboardShown)
return;
_isKeyboardShown = true;
var activeView = View.FindFirstResponder();
if (activeView == null)
return;
var keyboardFrame = UIKeyboard.FrameEndFromNotification(notification);
var isOverlapping = activeView.IsKeyboardOverlapping(View, keyboardFrame);
if (!isOverlapping)
return;
if (isOverlapping)
{
_activeViewBottom = activeView.GetViewRelativeBottom(View);
ShiftPageUp(keyboardFrame.Height, _activeViewBottom);
}
}
private void OnKeyboardHide(NSNotification notification)
{
if (!IsViewLoaded)
return;
_isKeyboardShown = false;
var keyboardFrame = UIKeyboard.FrameEndFromNotification(notification);
if (_pageWasShiftedUp)
{
ShiftPageDown(keyboardFrame.Height, _activeViewBottom);
}
}
private void ShiftPageUp(nfloat keyboardHeight, double activeViewBottom)
{
var pageFrame = Element.Bounds;
var newHeight = pageFrame.Height + CalculateShiftByAmount(pageFrame.Height, keyboardHeight, activeViewBottom);
Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
pageFrame.Width, newHeight));
_pageWasShiftedUp = true;
}
private void ShiftPageDown(nfloat keyboardHeight, double activeViewBottom)
{
var pageFrame = Element.Bounds;
var newHeight = pageFrame.Height + keyboardHeight;
Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
pageFrame.Width, newHeight));
_pageWasShiftedUp = false;
}
private double CalculateShiftByAmount(double pageHeight, nfloat keyboardHeight, double activeViewBottom)
{
return (pageHeight - activeViewBottom) - keyboardHeight;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment