Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyboardExtensions #1064

Merged
merged 30 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ffefe46
KeyboardManager
PureWeen Mar 5, 2023
ea810c2
- simplify references
PureWeen Mar 5, 2023
ec9a2d0
Merge branch 'main' into keyboardmanager
PureWeen Mar 8, 2023
f93dd04
- review comments and rename to KeyboardExtensions
PureWeen Mar 8, 2023
2720ec5
Updates summaries and APIs
PureWeen Mar 8, 2023
c3dac98
- fix text
PureWeen Mar 8, 2023
7f91327
- add tizen file
PureWeen Mar 8, 2023
8dde14d
Review comments
PureWeen Mar 9, 2023
4151a9b
Merge branch 'main' into keyboardmanager
VladislavAntonyuk Mar 9, 2023
8c85440
Update src/CommunityToolkit.Maui.Core/Platform/KeyboardManager/Keyboa…
PureWeen Mar 9, 2023
5af7b0c
Update src/CommunityToolkit.Maui.Core/Platform/KeyboardManager/Keyboa…
PureWeen Mar 9, 2023
db453ce
- value task
PureWeen Mar 9, 2023
196af53
Merge branch 'main' into keyboardmanager
brminnick Mar 10, 2023
d500dfc
Handle Exceptions using `showKeyboardTCS.SetException(e)`
brminnick Mar 10, 2023
2364741
Update Formatting. Change `[UnsupportedOSPlatform("MacOS")]` -> `[Uns…
brminnick Mar 10, 2023
f83114a
Update Formatting
brminnick Mar 10, 2023
e4cc32f
Remove Unused Controls. Add `KeyboardExtension` label
brminnick Mar 10, 2023
57421dc
Handle Exceptions. Update Formatting. Remove Unused Code
brminnick Mar 10, 2023
24b7540
Rename Folder from `KeyboardManager` -> `KeyboardExtensions`
brminnick Mar 10, 2023
2a93247
Remove unused usings
brminnick Mar 10, 2023
9743c8d
Throw `NotImplementedException`
brminnick Mar 10, 2023
a6be3c8
Update Formatting
brminnick Mar 10, 2023
88c7457
Add `TryGetInputPane()`
brminnick Mar 10, 2023
ffffbea
Merge branch 'main' into keyboardmanager
pictos Mar 10, 2023
63483a7
Add Tizen implementation
JoonghyunCho Mar 13, 2023
bc8ba16
Merge branch 'main' into keyboardmanager
PureWeen Mar 14, 2023
f822d32
- add comment and code to better validate Keyboard Extensions
PureWeen Mar 14, 2023
41f1141
Merge branch 'main' into keyboardmanager
PureWeen Mar 17, 2023
4fdfae0
Merge branch 'main' into keyboardmanager
brminnick Apr 11, 2023
bdaee76
Merge branch 'main' into keyboardmanager
jfversluis Apr 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
using CommunityToolkit.Maui.Sample.ViewModels.Converters;
using CommunityToolkit.Maui.Sample.ViewModels.Essentials;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;
using CommunityToolkit.Maui.Sample.ViewModels.ImageSources;
using CommunityToolkit.Maui.Sample.ViewModels.Layouts;
using CommunityToolkit.Maui.Sample.ViewModels.Views;
Expand Down Expand Up @@ -87,6 +88,7 @@ public partial class AppShell : Shell

// Add Extensions View Models
CreateViewModelMapping<ColorAnimationExtensionsPage, ColorAnimationExtensionsViewModel, ExtensionsGalleryPage, ExtensionsGalleryViewModel>(),
CreateViewModelMapping<KeyboardExtensionsPage, KeyboardExtensionsViewModel, ExtensionsGalleryPage, ExtensionsGalleryViewModel>(),

// Add ImageSources View Models
CreateViewModelMapping<GravatarImageSourcePage, GravatarImageSourceViewModel, ImageSourcesGalleryPage, ImageSourcesGalleryViewModel>(),
Expand Down
2 changes: 2 additions & 0 deletions samples/CommunityToolkit.Maui.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
using CommunityToolkit.Maui.Sample.ViewModels.Converters;
using CommunityToolkit.Maui.Sample.ViewModels.Essentials;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;
using CommunityToolkit.Maui.Sample.ViewModels.ImageSources;
using CommunityToolkit.Maui.Sample.ViewModels.Layouts;
using CommunityToolkit.Maui.Sample.ViewModels.Views;
Expand Down Expand Up @@ -156,6 +157,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)

// Add Extensions Pages + ViewModels
services.AddTransientWithShellRoute<ColorAnimationExtensionsPage, ColorAnimationExtensionsViewModel>();
services.AddTransientWithShellRoute<KeyboardExtensionsPage, KeyboardExtensionsViewModel>();

// Add ImageSources Pages + ViewModels
services.AddTransientWithShellRoute<GravatarImageSourcePage, GravatarImageSourceViewModel>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using CommunityToolkit.Maui.Sample.Pages;
using CommunityToolkit.Maui.Sample.ViewModels.Behaviors;

namespace CommunityToolkit.Maui.Sample.Pages.Behaviors;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<pages:BasePage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
x:Class="CommunityToolkit.Maui.Sample.Pages.Extensions.KeyboardExtensionsPage"
Title="KeyboardExtensionsPage"
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Extensions"
x:TypeArguments="vm:KeyboardExtensionsViewModel"
x:DataType="vm:KeyboardExtensionsViewModel">
<pages:BasePage.Content>
<ScrollView>
<VerticalStackLayout Spacing="12">
<Label Text="The Keyboard extension method provides an easy way to open and close the SoftInput Keyboard device on platforms that support it."
HorizontalOptions="Center"
HorizontalTextAlignment="Center"/>

<Label Text="{Binding OperationResult}"></Label>

<Entry Text="" x:Name="entryToFocus" Focused="OnEntryFocused"></Entry>

<Button Text="Show Keyboard" CommandParameter="{x:Reference Name=entryToFocus}" Command="{Binding ShowKeyboardCommand}"></Button>
<Button Text="Hide Keyboard" CommandParameter="{x:Reference Name=entryToFocus}" Command="{Binding HideKeyboardCommand}"></Button>
<Button Text="Check Keyboard State" CommandParameter="{x:Reference Name=entryToFocus}" Command="{Binding IsKeyboardShowingCommand}"></Button>

</VerticalStackLayout>
</ScrollView>

</pages:BasePage.Content>
</pages:BasePage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;

namespace CommunityToolkit.Maui.Sample.Pages.Extensions;

public partial class KeyboardExtensionsPage : BasePage<KeyboardExtensionsViewModel>
{
public KeyboardExtensionsPage(KeyboardExtensionsViewModel viewModel) :
base(viewModel)
{
InitializeComponent();
}

void OnEntryFocused(System.Object sender, Microsoft.Maui.Controls.FocusEventArgs e)
{
#if IOS || MACCATALYST
// Currently .NET MAUI will auto close the keyboard on iOS if you click outside of the entry
// This causes the examples on this page to behave oddly, because the keybord auto closes if the user
// taps the "hide keyboard" or "check keyboard status" buttons.
// We're going to remove this as the default behavior in .NET 8 and then users can re-enable it via
// https://github.com/CommunityToolkit/Maui/issues/978
// This code removes the TapGestureRecognizer used to detect and close the keyboard so that we can accurately
// validate that these APIs work on iOS
if (this?.Handler?.PlatformView is UIKit.UIView uiView &&
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
uiView.GestureRecognizers is not null)
{
foreach (var gesture in uiView.GestureRecognizers)
{
if (gesture is UIKit.UITapGestureRecognizer gr)
{
uiView.RemoveGestureRecognizer(gr);
break;
}
}
}
#endif
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using CommunityToolkit.Maui.Extensions;
using CommunityToolkit.Maui.Core.Platform;
using CommunityToolkit.Maui.Extensions;
using CommunityToolkit.Maui.Sample.Models;
using CommunityToolkit.Maui.Sample.ViewModels.Extensions;

namespace CommunityToolkit.Maui.Sample.ViewModels.Converters;

Expand All @@ -10,6 +12,9 @@ public ExtensionsGalleryViewModel()
{
SectionModel.Create<ColorAnimationExtensionsViewModel>(nameof(ColorAnimationExtensions),
"Extension methods that provide color animations"),

SectionModel.Create<KeyboardExtensionsViewModel>(nameof(KeyboardExtensions),
"Extension methods that provide keyboard interactions"),
})
{

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using CommunityToolkit.Maui.Core.Platform;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace CommunityToolkit.Maui.Sample.ViewModels.Extensions;

public partial class KeyboardExtensionsViewModel : BaseViewModel
{
[ObservableProperty]
string operationResult = string.Empty;

[RelayCommand]
void OnIsKeyboardShowing(ITextInput view)
{
if (view.IsSoftKeyboardShowing())
{
OperationResult = $"Soft Input Is Currently Showing";
}
else
{
OperationResult = $"Soft Input Is Currently Hidden";
}
}

[RelayCommand]
async Task OnHideKeyboard(ITextInput view, CancellationToken token)
{
try
{
bool isSuccessful = await view.HideKeyboardAsync(token);

if (isSuccessful)
{
OperationResult = "Hide Succeeded";
}
else
{
OperationResult = "Hide Failed";
}
}
catch (Exception e)
{
OperationResult = e.Message;
}
}

[RelayCommand]
async Task OnShowKeyboard(ITextInput view, CancellationToken token)
{
try
{
bool isSuccessful = await view.ShowKeyboardAsync(CancellationToken.None);

if (isSuccessful)
{
OperationResult = "Show Succeeded";
}
else
{
OperationResult = "Show Failed";
}
}
catch (Exception e)
{
OperationResult = e.Message;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Android.Content;
using Android.Views;
using Android.Views.InputMethods;
using AndroidX.Core.View;
using Microsoft.Maui.Platform;
using AView = Android.Views.View;

namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardExtensions
{
static bool HideKeyboard(this AView inputView)
{
var focusedView = inputView.Context?.GetActivity()?.Window?.CurrentFocus;
AView tokenView = focusedView ?? inputView;

using var inputMethodManager = (InputMethodManager?)tokenView.Context?.GetSystemService(Context.InputMethodService);
var windowToken = tokenView.WindowToken;

if (windowToken is not null && inputMethodManager is not null)
{
return inputMethodManager.HideSoftInputFromWindow(windowToken, HideSoftInputFlags.None);
}

return false;
}

static bool ShowKeyboard(this TextView inputView)
{
using var inputMethodManager = (InputMethodManager?)inputView.Context?.GetSystemService(Context.InputMethodService);

// The zero value for the second parameter comes from
// https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#showSoftInput(android.view.View,%20int)
// Apparently there's no named value for zero in this case
return inputMethodManager?.ShowSoftInput(inputView, 0) is true;
}

static bool ShowKeyboard(this AView view) => view switch
{
TextView textView => textView.ShowKeyboard(),
ViewGroup viewGroup => viewGroup.GetFirstChildOfType<TextView>()?.ShowKeyboard() is true,
_ => false,
};

static bool IsSoftKeyboardShowing(this AView view)
{
var insets = ViewCompat.GetRootWindowInsets(view);
if (insets is null)
{
return false;
}

var result = insets.IsVisible(WindowInsetsCompat.Type.Ime());
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardExtensions
{
static bool HideKeyboard(this UIView inputView) => inputView.ResignFirstResponder();

static bool ShowKeyboard(this UIView inputView) => inputView.BecomeFirstResponder();

static bool IsSoftKeyboardShowing(this UIView inputView) => inputView.IsFirstResponder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Runtime.Versioning;

namespace CommunityToolkit.Maui.Core.Platform;

[UnsupportedOSPlatform("MacCatalyst")]
public static partial class KeyboardExtensions
{
static bool HideKeyboard(this UIView inputView) => throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");

static bool ShowKeyboard(this UIView inputView) => throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");

static bool IsSoftKeyboardShowing(this UIView inputView) => throw new NotSupportedException("MacOS does not currently support opening the SoftKeyboard");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CommunityToolkit.Maui.Core.Platform;

public static partial class KeyboardExtensions
{
static bool HideKeyboard(this object _) => throw new NotSupportedException();

static bool ShowKeyboard(this object _) => throw new NotSupportedException();

static bool IsSoftKeyboardShowing(this object _) => throw new NotSupportedException();
}
Loading