-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
SoftInputExtensions.cs
157 lines (136 loc) · 4.13 KB
/
SoftInputExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using System.Diagnostics.CodeAnalysis;
using Microsoft.Maui.Dispatching;
using Microsoft.Maui.Platform;
using System.Threading.Tasks;
using System.Threading;
using System;
#if IOS || MACCATALYST
using PlatformView = UIKit.UIView;
#elif ANDROID
using PlatformView = Android.Views.View;
#elif WINDOWS
using PlatformView = Microsoft.UI.Xaml.FrameworkElement;
#elif TIZEN
using PlatformView = Tizen.NUI.BaseComponents.View;
#elif (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID && !TIZEN)
using PlatformView = System.Object;
using IPlatformViewHandler = Microsoft.Maui.IViewHandler;
#endif
namespace Microsoft.Maui;
/// <summary>
/// Extension methods for interacting with a platform's Soft Input Pane
/// </summary>
public static partial class SoftInputExtensions
{
/// <summary>
/// If a soft input pane is currently showing, this will attempt to hide it.
/// </summary>
/// <param name="targetView"></param>
/// <param name="token">Cancellation token</param>
/// <returns>
/// Returns <c>true</c> if the platform was able to hide the soft input pane.</returns>
public static Task<bool> HideSoftInputAsync(this ITextInput targetView, CancellationToken token)
{
#if NETSTANDARD
return Task.FromResult(false);
#else
token.ThrowIfCancellationRequested();
if (!targetView.TryGetPlatformView(out var platformView, out _, out _))
{
return Task.FromResult(false);
}
return Task.FromResult(platformView.HideSoftInput());
#endif
}
/// <summary>
/// If a soft input pane is currently hiding, this will attempt to show it.
/// </summary>
/// <param name="targetView"></param>
/// <param name="token">Cancellation token</param>
/// <returns>
/// Returns <c>true</c> if the platform was able to show the soft input pane.</returns>
public static Task<bool> ShowSoftInputAsync(this ITextInput targetView, CancellationToken token)
{
#if NETSTANDARD
return Task.FromResult(false);
#else
token.ThrowIfCancellationRequested();
if (!targetView.TryGetPlatformView(out var platformView, out var handler, out var view))
{
return Task.FromResult(false);
}
if (!view.IsFocused)
{
var showKeyboardTCS = new TaskCompletionSource<bool>();
#pragma warning disable CS0618
handler.Invoke(nameof(IView.Focus), new FocusRequest(false));
#pragma warning restore CS0618
handler.GetRequiredService<IDispatcher>().Dispatch(() =>
{
try
{
var result = platformView.ShowSoftInput();
showKeyboardTCS.SetResult(result);
}
catch (Exception e)
{
showKeyboardTCS.SetException(e);
}
});
return showKeyboardTCS.Task.WaitAsync(token);
}
else
{
var result = platformView.ShowSoftInput();
return Task.FromResult(result).WaitAsync(token);
}
#endif
}
/// <summary>
/// Checks to see if the platform is currently showing the soft input pane
/// </summary>
/// <param name="targetView"></param>
/// <returns>
/// Returns <c>true</c> if the soft input pane is currently showing.</returns>
public static bool IsSoftInputShowing(this ITextInput targetView)
{
if (!targetView.TryGetPlatformView(out PlatformView? platformView, out _, out _))
{
return false;
}
return platformView.IsSoftInputShowing();
}
static bool TryGetPlatformView(this ITextInput textInput,
[NotNullWhen(true)] out PlatformView? platformView,
[NotNullWhen(true)] out IPlatformViewHandler? handler,
[NotNullWhen(true)] out IView? view)
{
if (textInput is not IView iView ||
iView.Handler is not IPlatformViewHandler platformViewHandler)
{
platformView = null;
handler = null;
view = null;
return false;
}
if (iView.Handler?.PlatformView is not PlatformView platform)
{
platformView = null;
handler = null;
view = null;
return false;
}
handler = platformViewHandler;
platformView = platform;
view = iView;
return true;
}
}
#if NETSTANDARD || !PLATFORM
public static partial class SoftInputExtensions
{
static bool HideSoftInput(this object _) => throw new NotSupportedException();
static bool ShowSoftInput(this object _) => throw new NotSupportedException();
static bool IsSoftInputShowing(this object _) => throw new NotSupportedException();
}
#endif