diff --git a/src/Compatibility/Core/src/Android/Extensions/EntryRendererExtensions.cs b/src/Compatibility/Core/src/Android/Extensions/EntryRendererExtensions.cs
index b90f3377054a..ebb184154bab 100644
--- a/src/Compatibility/Core/src/Android/Extensions/EntryRendererExtensions.cs
+++ b/src/Compatibility/Core/src/Android/Extensions/EntryRendererExtensions.cs
@@ -4,7 +4,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
internal static class EntryRendererExtensions
{
-
+ [PortHandler]
internal static ImeAction ToAndroidImeAction(this ReturnType returnType)
{
switch (returnType)
diff --git a/src/Compatibility/Core/src/Android/Renderers/EntryRenderer.cs b/src/Compatibility/Core/src/Android/Renderers/EntryRenderer.cs
index f272913392e0..f2acf4d9d985 100644
--- a/src/Compatibility/Core/src/Android/Renderers/EntryRenderer.cs
+++ b/src/Compatibility/Core/src/Android/Renderers/EntryRenderer.cs
@@ -397,6 +397,7 @@ void UpdateCharacterSpacing()
}
}
+ [PortHandler]
void UpdateReturnType()
{
if (Control == null || Element == null)
diff --git a/src/Compatibility/Core/src/iOS/Extensions/Extensions.cs b/src/Compatibility/Core/src/iOS/Extensions/Extensions.cs
index e2d7ce489a45..607ee88e1371 100644
--- a/src/Compatibility/Core/src/iOS/Extensions/Extensions.cs
+++ b/src/Compatibility/Core/src/iOS/Extensions/Extensions.cs
@@ -111,6 +111,7 @@ internal static UISearchBarStyle ToNativeSearchBarStyle(this PlatformConfigurati
}
}
+ [PortHandler]
internal static UIReturnKeyType ToUIReturnKeyType(this ReturnType returnType)
{
switch (returnType)
diff --git a/src/Compatibility/Core/src/iOS/Renderers/EntryRenderer.cs b/src/Compatibility/Core/src/iOS/Renderers/EntryRenderer.cs
index f928479f3430..af236d754bcf 100644
--- a/src/Compatibility/Core/src/iOS/Renderers/EntryRenderer.cs
+++ b/src/Compatibility/Core/src/iOS/Renderers/EntryRenderer.cs
@@ -402,6 +402,7 @@ bool ShouldChangeCharacters(UITextField textField, NSRange range, string replace
return newLength <= Element?.MaxLength;
}
+ [PortHandler]
void UpdateReturnType()
{
if (Control == null || Element == null)
diff --git a/src/Core/src/Core/IEntry.cs b/src/Core/src/Core/IEntry.cs
index ee68a73a818a..e07f92c10101 100644
--- a/src/Core/src/Core/IEntry.cs
+++ b/src/Core/src/Core/IEntry.cs
@@ -14,5 +14,10 @@ public interface IEntry : IView, IText, ITextInput, ITextAlignment
/// Gets a value that controls whether text prediction and automatic text correction is on or off.
///
bool IsTextPredictionEnabled { get; }
+
+ ///
+ /// Gets an enumeration value that controls the appearance of the return button.
+ ///
+ ReturnType ReturnType { get; }
}
}
\ No newline at end of file
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.Android.cs b/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
index bbbbe8a2c76d..f1c84c4f4e36 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.Android.cs
@@ -79,6 +79,11 @@ public static void MapIsReadOnly(EntryHandler handler, IEntry entry)
handler.TypedNativeView?.UpdateIsReadOnly(entry);
}
+ public static void MapReturnType(EntryHandler handler, IEntry entry)
+ {
+ handler.TypedNativeView?.UpdateReturnType(entry);
+ }
+
void OnTextChanged(string? text)
{
if (VirtualView == null || TypedNativeView == null)
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.Standard.cs b/src/Core/src/Handlers/Entry/EntryHandler.Standard.cs
index 1f5c439cb04e..4900bd45e574 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.Standard.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.Standard.cs
@@ -14,5 +14,6 @@ public static void MapIsTextPredictionEnabled(IViewHandler handler, IEntry entry
public static void MapPlaceholder(IViewHandler handler, IEntry entry) { }
public static void MapIsReadOnly(IViewHandler handler, IEntry entry) { }
public static void MapFont(IViewHandler handler, IEntry entry) { }
+ public static void MapReturnType(IViewHandler handler, IEntry entry) { }
}
}
\ No newline at end of file
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.cs b/src/Core/src/Handlers/Entry/EntryHandler.cs
index b16011295ad5..aa1e935c99a6 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.cs
@@ -11,7 +11,8 @@ public partial class EntryHandler
[nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled,
[nameof(IEntry.Placeholder)] = MapPlaceholder,
[nameof(IEntry.IsReadOnly)] = MapIsReadOnly,
- [nameof(IEntry.Font)] = MapFont
+ [nameof(IEntry.Font)] = MapFont,
+ [nameof(IEntry.ReturnType)] = MapReturnType
};
public EntryHandler() : base(EntryMapper)
diff --git a/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs b/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
index 70e29a1d8766..aaa9e49221f6 100644
--- a/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
+++ b/src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
@@ -77,6 +77,11 @@ public static void MapIsReadOnly(EntryHandler handler, IEntry entry)
handler.TypedNativeView?.UpdateIsReadOnly(entry);
}
+ public static void MapReturnType(EntryHandler handler, IEntry entry)
+ {
+ handler.TypedNativeView?.UpdateReturnType(entry);
+ }
+
void OnEditingChanged(object? sender, EventArgs e) => OnTextChanged();
void OnEditingEnded(object? sender, EventArgs e) => OnTextChanged();
diff --git a/src/Core/src/Platform/Android/EntryExtensions.cs b/src/Core/src/Platform/Android/EntryExtensions.cs
index 22de0444020a..fa0ed5a1cbb5 100644
--- a/src/Core/src/Platform/Android/EntryExtensions.cs
+++ b/src/Core/src/Platform/Android/EntryExtensions.cs
@@ -102,5 +102,10 @@ internal static void SetInputType(this AppCompatEditText editText, IEntry entry)
if (entry.IsReadOnly)
editText.InputType = InputTypes.Null;
}
+
+ public static void UpdateReturnType(this AppCompatEditText editText, IEntry entry)
+ {
+ editText.ImeOptions = entry.ReturnType.ToNative();
+ }
}
}
diff --git a/src/Core/src/Platform/Android/ImeActionExtensions.cs b/src/Core/src/Platform/Android/ImeActionExtensions.cs
new file mode 100644
index 000000000000..1a208bd21b73
--- /dev/null
+++ b/src/Core/src/Platform/Android/ImeActionExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+using Android.Views.InputMethods;
+
+namespace Microsoft.Maui
+{
+ public static class ImeActionExtensions
+ {
+ public static ImeAction ToNative(this ReturnType returnType)
+ {
+ switch (returnType)
+ {
+ case ReturnType.Go:
+ return ImeAction.Go;
+ case ReturnType.Next:
+ return ImeAction.Next;
+ case ReturnType.Send:
+ return ImeAction.Send;
+ case ReturnType.Search:
+ return ImeAction.Search;
+ case ReturnType.Done:
+ return ImeAction.Done;
+ case ReturnType.Default:
+ return ImeAction.Done;
+ default:
+ throw new NotImplementedException($"ReturnType {returnType} not supported");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Core/src/Platform/iOS/EntryExtensions.cs b/src/Core/src/Platform/iOS/EntryExtensions.cs
index 6ce7961a6000..861c08eaf577 100644
--- a/src/Core/src/Platform/iOS/EntryExtensions.cs
+++ b/src/Core/src/Platform/iOS/EntryExtensions.cs
@@ -69,5 +69,10 @@ public static void UpdateFont(this UITextField textField, IEntry entry, IFontMan
var uiFont = fontManager.GetFont(entry.Font);
textField.Font = uiFont;
}
+
+ public static void UpdateReturnType(this UITextField textField, IEntry entry)
+ {
+ textField.ReturnKeyType = entry.ReturnType.ToNative();
+ }
}
}
\ No newline at end of file
diff --git a/src/Core/src/Platform/iOS/ReturnKeyTypeExtensions.cs b/src/Core/src/Platform/iOS/ReturnKeyTypeExtensions.cs
new file mode 100644
index 000000000000..d6092fc99e7e
--- /dev/null
+++ b/src/Core/src/Platform/iOS/ReturnKeyTypeExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+using UIKit;
+
+namespace Microsoft.Maui
+{
+ public static class ReturnKeyTypeExtensions
+ {
+ public static UIReturnKeyType ToNative(this ReturnType returnType)
+ {
+ switch (returnType)
+ {
+ case ReturnType.Go:
+ return UIReturnKeyType.Go;
+ case ReturnType.Next:
+ return UIReturnKeyType.Next;
+ case ReturnType.Send:
+ return UIReturnKeyType.Send;
+ case ReturnType.Search:
+ return UIReturnKeyType.Search;
+ case ReturnType.Done:
+ return UIReturnKeyType.Done;
+ case ReturnType.Default:
+ return UIReturnKeyType.Default;
+ default:
+ throw new NotImplementedException($"ReturnType {returnType} not supported");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs
index 887cd14e4b06..c89500f8cf86 100644
--- a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs
+++ b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.Android.cs
@@ -1,11 +1,12 @@
using System.Threading.Tasks;
using Android.Text;
+using Android.Views.InputMethods;
using AndroidX.AppCompat.Widget;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Xunit;
-using AColor = global::Android.Graphics.Color;
+using AColor = Android.Graphics.Color;
namespace Microsoft.Maui.DeviceTests
{
@@ -38,6 +39,31 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultTypeface, nativeEntry.Typeface);
}
+ [Fact(DisplayName = "ReturnType Initializes Correctly")]
+ public async Task ReturnTypeInitializesCorrectly()
+ {
+ var xplatReturnType = ReturnType.Next;
+ var entry = new EntryStub()
+ {
+ Text = "Test",
+ ReturnType = xplatReturnType
+ };
+
+ ImeAction expectedValue = ImeAction.Next;
+
+ var values = await GetValueAsync(entry, (handler) =>
+ {
+ return new
+ {
+ ViewValue = entry.ReturnType,
+ NativeViewValue = GetNativeReturnType(handler)
+ };
+ });
+
+ Assert.Equal(xplatReturnType, values.ViewValue);
+ Assert.Equal(expectedValue, values.NativeViewValue);
+ }
+
[Fact(DisplayName = "Horizontal TextAlignment Initializes Correctly")]
public async Task HorizontalTextAlignmentInitializesCorrectly()
{
@@ -113,5 +139,8 @@ bool GetNativeIsItalic(EntryHandler entryHandler) =>
Android.Views.TextAlignment GetNativeTextAlignment(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).TextAlignment;
+
+ ImeAction GetNativeReturnType(EntryHandler entryHandler) =>
+ GetNativeEntry(entryHandler).ImeOptions;
}
}
\ No newline at end of file
diff --git a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
index e696e05e8867..9788e9329761 100644
--- a/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
+++ b/src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
@@ -59,6 +59,32 @@ public async Task HorizontalTextAlignmentInitializesCorrectly()
Assert.Equal(xplatHorizontalTextAlignment, values.ViewValue);
values.NativeViewValue.AssertHasFlag(expectedValue);
}
+
+ [Fact(DisplayName = "ReturnType Initializes Correctly")]
+ public async Task ReturnTypeInitializesCorrectly()
+ {
+ var xplatReturnType = ReturnType.Next;
+ var entry = new EntryStub()
+ {
+ Text = "Test",
+ ReturnType = xplatReturnType
+ };
+
+ UIReturnKeyType expectedValue = UIReturnKeyType.Next;
+
+ var values = await GetValueAsync(entry, (handler) =>
+ {
+ return new
+ {
+ ViewValue = entry.ReturnType,
+ NativeViewValue = GetNativeReturnType(handler)
+ };
+ });
+
+ Assert.Equal(xplatReturnType, values.ViewValue);
+ Assert.Equal(expectedValue, values.NativeViewValue);
+ }
+
UITextField GetNativeEntry(EntryHandler entryHandler) =>
(UITextField)entryHandler.View;
@@ -95,5 +121,8 @@ bool GetNativeIsItalic(EntryHandler entryHandler) =>
UITextAlignment GetNativeTextAlignment(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).TextAlignment;
+
+ UIReturnKeyType GetNativeReturnType(EntryHandler entryHandler) =>
+ GetNativeEntry(entryHandler).ReturnKeyType;
}
}
\ No newline at end of file
diff --git a/src/Core/tests/DeviceTests/Stubs/EntryStub.cs b/src/Core/tests/DeviceTests/Stubs/EntryStub.cs
index f2a4e27df32c..026fbec2f611 100644
--- a/src/Core/tests/DeviceTests/Stubs/EntryStub.cs
+++ b/src/Core/tests/DeviceTests/Stubs/EntryStub.cs
@@ -28,6 +28,8 @@ public string Text
public TextAlignment HorizontalTextAlignment { get; set; }
+ public ReturnType ReturnType { get; set; }
+
public event EventHandler> TextChanged;
void OnTextChanged(string oldValue, string newValue) =>