diff --git a/src/Compatibility/Core/src/Android/Renderers/EditorRenderer.cs b/src/Compatibility/Core/src/Android/Renderers/EditorRenderer.cs index 291e4068d141..e39a8dd5c4de 100644 --- a/src/Compatibility/Core/src/Android/Renderers/EditorRenderer.cs +++ b/src/Compatibility/Core/src/Android/Renderers/EditorRenderer.cs @@ -216,6 +216,7 @@ protected virtual void UpdateFont() EditText.SetTextSize(ComplexUnitType.Sp, (float)Element.FontSize); } + [PortHandler("Partially Ported")] void UpdateInputType() { Editor model = Element; diff --git a/src/Compatibility/Core/src/iOS/Renderers/EditorRenderer.cs b/src/Compatibility/Core/src/iOS/Renderers/EditorRenderer.cs index 0a83d4b21862..1cc992db5c51 100644 --- a/src/Compatibility/Core/src/iOS/Renderers/EditorRenderer.cs +++ b/src/Compatibility/Core/src/iOS/Renderers/EditorRenderer.cs @@ -306,6 +306,7 @@ protected internal virtual void UpdateFont() TextView.Font = font; } + [PortHandler("Partially Ported")] void UpdateKeyboard() { var keyboard = Element.Keyboard; diff --git a/src/Controls/samples/Controls.Sample/Pages/MainPage.cs b/src/Controls/samples/Controls.Sample/Pages/MainPage.cs index a2f5462f2eae..2ba443aee005 100644 --- a/src/Controls/samples/Controls.Sample/Pages/MainPage.cs +++ b/src/Controls/samples/Controls.Sample/Pages/MainPage.cs @@ -85,6 +85,7 @@ void SetupMauiLayout() verticalStack.Add(new Editor()); verticalStack.Add(new Editor { Text = "Editor" }); + verticalStack.Add(new Editor { Text = "Predictive Text Off", IsTextPredictionEnabled = false }); var entry = new Entry(); entry.TextChanged += (sender, e) => diff --git a/src/Core/src/Core/IEditor.cs b/src/Core/src/Core/IEditor.cs index f9dfe526edc6..d1cbf366f1ab 100644 --- a/src/Core/src/Core/IEditor.cs +++ b/src/Core/src/Core/IEditor.cs @@ -5,6 +5,9 @@ /// public interface IEditor : IView, IText { - + /// + /// Gets a value that controls whether text prediction and automatic text correction is on or off. + /// + bool IsTextPredictionEnabled { get; } } } \ No newline at end of file diff --git a/src/Core/src/Handlers/Editor/EditorHandler.Android.cs b/src/Core/src/Handlers/Editor/EditorHandler.Android.cs index 03a461f249d0..90b60ae24187 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.Android.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.Android.cs @@ -30,5 +30,10 @@ public static void MapCharacterSpacing(EditorHandler handler, IEditor editor) { handler.TypedNativeView?.UpdateCharacterSpacing(editor); } + + public static void MapPredictiveText(EditorHandler handler, IEditor editor) + { + handler.TypedNativeView?.UpdatePredictiveText(editor); + } } } \ No newline at end of file diff --git a/src/Core/src/Handlers/Editor/EditorHandler.Standard.cs b/src/Core/src/Handlers/Editor/EditorHandler.Standard.cs index 5af79cbefa11..a2bcc13f2635 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.Standard.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.Standard.cs @@ -7,6 +7,9 @@ public partial class EditorHandler : AbstractViewHandler protected override object CreateNativeView() => throw new NotImplementedException(); public static void MapText(IViewHandler handler, IEditor editor) { } + public static void MapCharacterSpacing(IViewHandler handler, IEditor editor) { } + + public static void MapPredictiveText(EditorHandler handler, IEditor editor) { } } } \ No newline at end of file diff --git a/src/Core/src/Handlers/Editor/EditorHandler.cs b/src/Core/src/Handlers/Editor/EditorHandler.cs index dbdc329c4ea7..2c4772a8112a 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.cs @@ -5,7 +5,8 @@ public partial class EditorHandler public static PropertyMapper EditorMapper = new PropertyMapper(ViewHandler.ViewMapper) { [nameof(IEditor.Text)] = MapText, - [nameof(IEditor.CharacterSpacing)] = MapCharacterSpacing + [nameof(IEditor.CharacterSpacing)] = MapCharacterSpacing, + [nameof(IEditor.IsTextPredictionEnabled)] = MapPredictiveText }; public EditorHandler() : base(EditorMapper) diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs index 66937026a805..60e981b18d31 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs @@ -1,4 +1,5 @@ -using CoreGraphics; +using System; +using CoreGraphics; using UIKit; namespace Microsoft.Maui.Handlers @@ -24,5 +25,10 @@ public static void MapCharacterSpacing(EditorHandler handler, IEditor editor) { handler.TypedNativeView?.UpdateCharacterSpacing(editor); } + + public static void MapPredictiveText(EditorHandler handler, IEditor editor) + { + handler.TypedNativeView?.UpdatePredictiveText(editor); + } } } \ No newline at end of file diff --git a/src/Core/src/Platform/Android/EditorExtensions.cs b/src/Core/src/Platform/Android/EditorExtensions.cs index ba6493dfdac6..849cb6fc8e7c 100644 --- a/src/Core/src/Platform/Android/EditorExtensions.cs +++ b/src/Core/src/Platform/Android/EditorExtensions.cs @@ -1,4 +1,5 @@ -using AndroidX.AppCompat.Widget; +using Android.Text; +using AndroidX.AppCompat.Widget; namespace Microsoft.Maui { @@ -23,5 +24,13 @@ public static void UpdateCharacterSpacing(this AppCompatEditText editText, IEdit { editText.LetterSpacing = editor.CharacterSpacing.ToEm(); } + + public static void UpdatePredictiveText(this AppCompatEditText editText, IEditor editor) + { + if(editor.IsTextPredictionEnabled) + return; + + editText.InputType |= InputTypes.TextFlagNoSuggestions; + } } } \ No newline at end of file diff --git a/src/Core/src/Platform/iOS/EditorExtensions.cs b/src/Core/src/Platform/iOS/EditorExtensions.cs index 7637cdb6ff4e..7f98d414201f 100644 --- a/src/Core/src/Platform/iOS/EditorExtensions.cs +++ b/src/Core/src/Platform/iOS/EditorExtensions.cs @@ -23,5 +23,11 @@ public static void UpdateCharacterSpacing(this UITextView textView, IEditor edit // TODO: Include AttributedText to Label Placeholder } + + public static void UpdatePredictiveText(this UITextView textView, IEditor editor) + { + textView.AutocorrectionType = editor.IsTextPredictionEnabled + ? UITextAutocorrectionType.Yes : UITextAutocorrectionType.No; + } } } \ No newline at end of file diff --git a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.Android.cs b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.Android.cs index 396bc1c8992b..91f40bf0e075 100644 --- a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.Android.cs +++ b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.Android.cs @@ -1,7 +1,8 @@ -using System.Threading.Tasks; +using Android.Text; using AndroidX.AppCompat.Widget; using Microsoft.Maui.DeviceTests.Stubs; using Microsoft.Maui.Handlers; +using System.Threading.Tasks; using Xunit; namespace Microsoft.Maui.DeviceTests @@ -39,6 +40,9 @@ public async Task CharacterSpacingInitializesCorrectly() string GetNativeText(EditorHandler editorHandler) => GetNativeEditor(editorHandler).Text; + + bool GetNativeIsTextPredictionEnabled(EditorHandler editorHandler) => + !GetNativeEditor(editorHandler).InputType.HasFlag(InputTypes.TextFlagNoSuggestions); double GetNativeCharacterSpacing(EditorHandler editorHandler) { diff --git a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs index ef3766c2b5c0..2a06d47d1996 100644 --- a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.cs @@ -46,5 +46,18 @@ public async Task TextUpdatesCorrectly(string setValue, string unsetValue) setValue, unsetValue); } + + [Theory(DisplayName = "Is Text Prediction Enabled")] + [InlineData(true)] + [InlineData(false)] + public async Task IsTextPredictionEnabledCorrectly(bool isEnabled) + { + var editor = new EditorStub() + { + IsTextPredictionEnabled = isEnabled + }; + + await ValidatePropertyInitValue(editor, () => editor.IsTextPredictionEnabled, GetNativeIsTextPredictionEnabled, isEnabled); + } } } \ No newline at end of file diff --git a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.iOS.cs index fb1574dc2e03..3cd059ed9584 100644 --- a/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Handlers/Editor/EditorHandlerTests.iOS.cs @@ -44,5 +44,8 @@ public async Task CharacterSpacingInitializesCorrectly() var editor = GetNativeEditor(editorHandler); return editor.AttributedText.GetCharacterSpacing(); } - } + + bool GetNativeIsTextPredictionEnabled(EditorHandler editorHandler) => + GetNativeEditor(editorHandler).AutocorrectionType == UITextAutocorrectionType.Yes; + } } \ No newline at end of file diff --git a/src/Core/tests/DeviceTests/Stubs/EditorStub.cs b/src/Core/tests/DeviceTests/Stubs/EditorStub.cs index 2f88d7829bff..70ca2d53096d 100644 --- a/src/Core/tests/DeviceTests/Stubs/EditorStub.cs +++ b/src/Core/tests/DeviceTests/Stubs/EditorStub.cs @@ -9,5 +9,7 @@ public partial class EditorStub : StubBase, IEditor public Font Font { get; set; } public double CharacterSpacing { get; set; } + + public bool IsTextPredictionEnabled { get; set; } } } \ No newline at end of file