Skip to content

Commit

Permalink
Refine Fix The popup with Entry can not show above of the keyboard. #9
Browse files Browse the repository at this point in the history
  • Loading branch information
microspaze committed May 12, 2024
1 parent 2820c2c commit 22ae8da
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 31 deletions.
31 changes: 22 additions & 9 deletions RGPopup.Maui/Pages/PopupPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace RGPopup.Maui.Pages
{
[ContentProperty("CoreContent")]
public class PopupPage : ContentPage
{
#region Internal Properties
Expand All @@ -24,7 +25,7 @@ public class PopupPage : ContentPage
#endregion

#region Bindable Properties

public static readonly BindableProperty IsPopupWindowResizableProperty = BindableProperty.Create(nameof(IsPopupWindowResizable), typeof(bool), typeof(PopupPage), false);

public bool IsPopupWindowResizable
Expand Down Expand Up @@ -137,6 +138,25 @@ public bool AndroidTalkbackAccessibilityWorkaround
set => SetValue(AndroidTalkbackAccessibilityWorkaroundProperty, value);
}

public static readonly BindableProperty CoreContentProperty = BindableProperty.Create(nameof(CoreContent), typeof(View), typeof(ContentPage), null, propertyChanged: OnContentChanged);

public View CoreContent
{
get => (View)GetValue(CoreContentProperty);
set => SetValue(CoreContentProperty, value);
}

public static void OnContentChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is not PopupPage popupPage) return;
var coreContent = newValue as View;
if (coreContent is not ContentView)
{
coreContent = new ContentView() { Content = coreContent, InputTransparent = false };
}
popupPage.Content = new ScrollView(){ Content = coreContent, InputTransparent = false };
}

#endregion

#region Main Methods
Expand All @@ -146,19 +166,12 @@ public PopupPage()
BackgroundColor = Color.FromArgb("#80000000");
InputTransparent = false;
}

/// <summary>
/// Fix if ContentPage's content is not ContentView or Grid, then the children will not display.
/// </summary>

protected override void OnParentSet()
{
if (this.Parent != null)
{
this.SendAppearing();
if (this.Content is not ContentView)
{
this.Content = new ContentView() { Content = this.Content, InputTransparent = false };
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Foundation;
using Microsoft.Maui.Controls.Platform;
using CoreGraphics;
using RGPopup.Maui.Pages;
using UIKit;

namespace RGPopup.Maui.Effects;
public class KeyboardOverlapFixPlatformEffect : PlatformEffect
{
private const double KeyboardOverlapAdjust = 0;
private static readonly bool IsIOS15 = DeviceInfo.Version.Major >= 15;

private UIView? _responderView;
private NSObject? _keyboardShowObserver;
Expand All @@ -21,7 +21,9 @@ public class KeyboardOverlapFixPlatformEffect : PlatformEffect
private bool _pageShiftedUp;
private bool _pageLoaded = false;

private ContentPage? CurrentPage => Element as ContentPage;
private PopupPage? CurrentPage => Element as PopupPage;
private ScrollView? ContentScrollView => CurrentPage?.Content as ScrollView;
private ContentView? ContentView => ContentScrollView?.Content as ContentView;

protected override void OnAttached()
{
Expand Down Expand Up @@ -81,19 +83,14 @@ private void OnKeyboardShow(NSNotification notification)

private void OnKeyboardShown(NSNotification notification)
{
if (!_pageLoaded || _responderView == null || _keyboardShown) return;
if (!_pageLoaded || _keyboardShown) return;

_keyboardShown = true;
var keyboardHeight = IsIOS15 ? _responderView.KeyboardLayoutGuide.LayoutFrame.Height : 0;
if (keyboardHeight <= 0)
{
var keyboardFrame = UIKeyboard.FrameEndFromNotification(notification);
keyboardHeight = keyboardFrame.Height;
}

var keyboardFrame = UIKeyboard.FrameEndFromNotification(notification);
var keyboardHeight = keyboardFrame.Height;
//Console.WriteLine($"KeyboardDidShowHeight: {keyboardHeight}");
if (keyboardHeight <= _keyboardHeight) return;
this.CheckOverlap(keyboardHeight);
if (keyboardHeight < _keyboardHeight) return;
this.CheckOverlap(keyboardHeight, force: true);
}

private void OnKeyboardHide(NSNotification notification)
Expand All @@ -109,9 +106,9 @@ private void OnKeyboardHide(NSNotification notification)
}
}

private void CheckOverlap(nfloat keyboardHeight)
private void CheckOverlap(nfloat keyboardHeight, bool force = false)
{
if (_pageShiftedUp) { return; }
if (_pageShiftedUp && !force) { return; }
var deltaHeight = keyboardHeight - _keyboardHeight;
if (_keyboardOverlap > 0 && deltaHeight > KeyboardOverlapAdjust)
{
Expand All @@ -125,7 +122,6 @@ private void CheckOverlap(nfloat keyboardHeight)
_responderView ??= FindFirstResponder(Control);
if (_responderView == null) return;
_keyboardOverlap = GetOverlapDistance(_responderView, Control, _keyboardHeight, false);
//Console.WriteLine($"KeyboardOverlap: {_keyboardOverlap}");
if (_keyboardOverlap > 0)
{
ShiftPageUp();
Expand All @@ -134,23 +130,24 @@ private void CheckOverlap(nfloat keyboardHeight)

private void ShiftPageUp()
{
if (CurrentPage == null || Control == null) return;
if (CurrentPage == null || ContentView == null || Control == null) return;
//Console.WriteLine($"KeyboardOverlap: {_keyboardOverlap}");
var deltaBottom = _keyboardOverlap + KeyboardOverlapAdjust;
_originalPadding ??= CurrentPage.Padding;
_currentPadding = new Thickness(_originalPadding.Value.Left, _originalPadding.Value.Top, _originalPadding.Value.Right, _originalPadding.Value.Bottom + deltaBottom);
_originalPadding ??= ContentView.Padding;
_currentPadding = new Thickness(_originalPadding.Value.Left, _originalPadding.Value.Top, _originalPadding.Value.Right, _originalPadding.Value.Bottom+deltaBottom);
CurrentPage.Dispatcher.Dispatch(() =>
{
CurrentPage.Padding = _currentPadding;
ContentView.Padding = _currentPadding;
});
_pageShiftedUp = true;
}

private void ShiftPageDown()
{
if (CurrentPage == null || _originalPadding == null) return;
if (CurrentPage == null || ContentView == null || _originalPadding == null) return;
CurrentPage.Dispatcher.Dispatch(() =>
{
CurrentPage.Padding = _originalPadding.Value;
ContentView.Padding = _originalPadding.Value;
});
_pageShiftedUp = false;
}
Expand Down
4 changes: 3 additions & 1 deletion RGPopup.Maui/Platforms/iOS/Platform/PopupWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ public override UIView HitTest(CGPoint point, UIEvent? uievent)
return null!;

var nativeView = pageHandler?.PlatformView;
var scrollView = formsElement.Content?.Handler?.PlatformView as UIView;
var contentView = scrollView?.Subviews?.FirstOrDefault();
var safePadding = formsElement.SafePadding;
if ((formsElement.BackgroundClickedCommand != null || formsElement.BackgroundInputTransparent || formsElement.CloseWhenBackgroundIsClicked)
&& Math.Max(SafeAreaInsets.Left, safePadding.Left) < point.X && point.X < (Bounds.Width-Math.Max(SafeAreaInsets.Right, safePadding.Right))
&& Math.Max(SafeAreaInsets.Top, safePadding.Top) < point.Y && point.Y < (Bounds.Height-Math.Max(SafeAreaInsets.Bottom, safePadding.Bottom))
&& (hitTestResult.Equals(nativeView) || hitTestResult.Equals(nativeView?.Subviews?.FirstOrDefault())))
&& (hitTestResult.Equals(nativeView) || hitTestResult.Equals(contentView) || hitTestResult.Equals(contentView?.Subviews?.FirstOrDefault())))
{
_ = formsElement.SendBackgroundClick();
if (formsElement.BackgroundInputTransparent)
Expand Down

0 comments on commit 22ae8da

Please sign in to comment.