Closed williambuchanan2 closed 2 months ago
The #2 issue from the first post here should be fixed and #3 is being discussed for the future. This long thread with different issues makes it harder to be sure the issues are getting full attention / we have proper reproduction so I'll close this thread after issue #1 is fixed, and we can start new issues with any other ios keyboard scrolling related things. This way, we can ensure the issues are getting proper attention, we can add them to the proper project boards, and we can try to get quicker fixes out to all of you. Thank you!
Unfortunately it seems that #3 is the critical part of the problem, and without a fix for that, from what I can see, the other fixes don't seem to have solved much. The end result is that we still lose access to half the page when the keyboard is showing.
Didn't this all work in Xamarin? Plus doesn't the native keyboard on the various platforms handle this stuff by default (i.e. moving the content up so it is accessible)? It seems strange that MAUI is somehow breaking this, what's the deal?
Didn't this all work in Xamarin? Plus doesn't the native keyboard on the various platforms handle this stuff by default (i.e. moving the content up so it is accessible)? It seems strange that MAUI is somehow breaking this, what's the deal?
To solve problem #1 in xamarin I had to create a CustomPageRenderer to get around the problem of pushing the list up. I tried using the same one on Maui, but was unsuccessful.
Good to know Xamarin wasn't perfect. Anecdotally, I just don't recall having end users complain so much about the keyboard. A good chunk of our bugs were related to keyboards overlapping screens and users getting "trapped" as buttons weren't tappable due to being scrolled offscreen. We've had to enable that "tap to close keyboard" attribute on almost every page to give users an escape hatch, but the UI looks naff when someone taps on an entry and has to key stuff in blind.
With Xamarin we didn't give it a second thought - we threw it all on the page and it just seemed to work like any other native app.
Didn't this all work in Xamarin? Plus doesn't the native keyboard on the various platforms handle this stuff by default (i.e. moving the content up so it is accessible)? It seems strange that MAUI is somehow breaking this, what's the deal?
I believe this has been an unresolved problem from the Xamarin years. Hard to believe it's been broken all those years. You would think the default behaviour on the platform would kick in but doesn't seem to be the case. The thing is it works perfectly on Android - all they have to do is make it work exactly the same way as Android but for some reason that doesn't seem to be happening.
I recently spent too much time coming up with a workaround to fix keyboard overlapping in my app.
In my case, we show a PageSheet modal with a large multiline Editor with a toolbar above it. I created a Behavior<View>
that resizes the height of the main ContentView in the page when the keyboard is opened.
More specifically, that Behavior<View>
decreases its bound View's height by the intersection Y
of the keyboard and the View. While I attached this behavior to the base ContentView we place in the modal page, it should work for any layout that you want to resize. Hopefully. I've only tested my specific scenario.
Project.Behaviors.SoftKbResizeBehavior.cs
:
namespace Project.Behaviors;
public partial class SoftKbResizeBehavior : Behavior<View>
{
View View { get; set; }
protected override void OnAttachedTo(View bindable)
{
base.OnAttachedTo(bindable);
View = bindable;
View.Loaded += View_Loaded;
View.Unloaded += View_Unloaded;
}
private void View_Loaded(object sender, EventArgs e)
{
Attach();
}
private void View_Unloaded(object sender, EventArgs e)
{
View.Loaded -= View_Loaded;
View.Unloaded -= View_Unloaded;
Detach();
}
partial void Attach();
partial void Detach();
}
Project.Platforms.iOS.Behaviors.SoftKbResizeBehavior.cs
:
// Adapted from https://developer.apple.com/documentation/uikit/uiresponder/1621578-keyboardframeenduserinfokey
using CoreGraphics;
using Foundation;
using Microsoft.Maui.Handlers;
using UIKit;
namespace Project.Behaviors;
public partial class SoftKbResizeBehavior
{
UIView UIView { get; set; }
NSObject ObserveWillChangeFrameToken { get; set; }
partial void Attach()
{
UIView = (View.Handler as ViewHandler).PlatformView;
ObserveWillChangeFrameToken = UIKeyboard.Notifications.ObserveWillChangeFrame(OnKeyboardWillChangeFrame);
}
partial void Detach()
{
ObserveWillChangeFrameToken.Dispose();
}
void OnKeyboardWillChangeFrame(object sender, UIKeyboardEventArgs e)
{
var intersection = CGRect.Intersect(UIView.Frame, e.FrameEnd);
if (intersection.IsEmpty)
{
View.HeightRequest = -1;
View.VerticalOptions = LayoutOptions.Fill;
}
else
{
var uiViewFrameInWindowCoordinateSpace = UIView.CoordinateSpace.ConvertRectToCoordinateSpace(
UIView.Frame, UIView.Window.CoordinateSpace);
var viewMaxY = uiViewFrameInWindowCoordinateSpace.GetMaxY();
var intMinY = intersection.GetMinY();
var offset = viewMaxY - intMinY;
View.HeightRequest = View.Height - offset;
View.VerticalOptions = LayoutOptions.Start;
}
}
}
Example of how I use it:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView>
<ContentView.Behaviors>
<behaviors:SoftKbResizeBehavior />
</ContentView.Behaviors>
<Border>
<StackLayout Orientation="Vertical">
<Grid>
<!-- Toolbar items here -->
</Grid>
<AbsoluteLayout VerticalOptions="FillAndExpand">
<Editor
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1" />
<!-- Views to float over the Editor -->
</AbsoluteLayout>
</StackLayout>
</Border>
</ContentView>
Notes:
ConvertRectToCoordinateSpace
call, you may need to convert it to your page's space instead of the Window, but I am a swift/iOS novice, so ¯\(ツ)/¯This problem also occurs in Xamarin.Forms, I solved it by adapting the following code XF issue and it still works today. For xamarin it is a PageRenderer, but for Maui I believe it should be a CustomPageController and CustomPageHandler, but I couldn't make it work. If anyone can manage it, it would be a great temporary fix for the problem.
Any update on this? Seems to still be broken from what I can see.
I recently spent too much time coming up with a workaround to fix keyboard overlapping in my app.
Thanks @tschbc that workaround was a huge help. I applied this behavior to all ScrollView
s in my app using a Style
to set the behavior. I still had to apply some manual scrolling adjustments as only the top line or two of my Editor was scrolling into view. In case anyone else is having similar issues, I adapted some stuff we had from XF which essentially consisted of:
Focus
and Unfocus
event handlers to my Editor
ScrollView
ancestorScrollY
(it has not started scrolling the control into focus yet)Scrolled
eventScrolled
event handler to wait for the animated auto-scroll to finishUnfocus
handler find the first ScrollView
ancestor and scroll back to the originally captured ScrollY
It's not perfect but seems to work well enough for now.
ETA: Oh, I forgot, I also had to change some ScrollView
s that had VerticalStackLayout
s as their child original child so that it was nested as the first row in a Grid
with RowDefinitions="Auto,*"
with a BoxView
in the bottom row to force it to take up vertical space if the content of the scroll view didn't take up the whole page.
ETA (Again 😅): I should probably mention that it appears the reason our editor may have required a little extra elbow grease is because it expands its height when it is focused (so it's the same height as an Entry until its focused). We tried a variety of approaches to get the size thing to work as close to our earlier XF version as best we could but none of them worked perfectly out-of-box. We went with using the common Visual States to adjust the height on focus in the end.
@TheXenocide Could you show us some code of your workaround? Would be very helpful, as I am struggling with the Editor
control myself at the moment.
Description
Exactly as documented here:
https://github.com/dotnet/maui/issues/14173#issue-1638336366
This issue was resolved in June last year and is now back in .NET 8.
Here are the iOS issues I see with the keyboard:
All the above is different to the behaviour on Android, and native iOS apps. If you can just get it to behave exactly like Android does then there won't be any problems.
Steps to Reproduce
Open reproduction app. Tap the "Keyboard Problem" button. Tap one of the top fields - soft keyboard shows. Now try to scroll down to get to one of the bottom fields on the form Notice bottom of form is not accessible when soft keyboard is showing.
Link to public reproduction project repository
https://github.com/williambuchanan2/MauiNavigation
Version with bug
8.0.3
Is this a regression from previous behavior?
Yes, this used to work in .NET MAUI
Last version that worked well
7.0.101
Affected platforms
iOS
Affected platform versions
No response
Did you find any workaround?
No
Relevant log output
No response