Skip to content

Commit

Permalink
fix(TextBox): [iOS] Add temporary workaround for iOS 16 on selection …
Browse files Browse the repository at this point in the history
…with UITextField

This change is needed to make the SinglelineTextBoxView.SelectedTextRange conditional, and avoid changing the value provided to UIKit. This breaks the use of `TextBoxSelectionChanged`, but can be restored by using the `FeatureConfiguration.TextBox.IOS16EnableSelectionSupport` feature flag if the issue ends up being fixed in UIKit. See #9430 for more details.
  • Loading branch information
jeromelaban committed Aug 31, 2022
1 parent 393ea67 commit c49c75d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/Uno.UI/FeatureConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,21 @@ public static class TextBlock

public static class TextBox
{

/// <summary>
/// Determines if the caret is visible or not.
/// </summary>
/// <remarks>This feature is used to avoid screenshot comparisons false positives</remarks>
public static bool HideCaret { get; set; } = false;

#if __IOS__
/// <summary>
/// As of iOS 16 Beta 4, the selection events are crashing the application. This feature configuration is added
/// to provide the ability to restore the original behavior if/when the underlying UIKit is fixed.
/// See https://github.com/unoplatform/uno/issues/9430 for additional details.
/// </summary>
public static bool IOS16EnableSelectionSupport { get; set; }
#endif
}

public static class ScrollViewer
Expand Down
39 changes: 38 additions & 1 deletion src/Uno.UI/UI/Xaml/Controls/TextBox/SinglelineTextBoxView.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
using Uno.UI.Controls;
using Windows.UI;
using Uno.Disposables;
using Foundation;
using Uno.Foundation.Logging;
using Uno.UI;
using static Uno.UI.FeatureConfiguration;

namespace Windows.UI.Xaml.Controls
{
Expand All @@ -19,6 +23,8 @@ public partial class SinglelineTextBoxView : UITextField, ITextBoxView, Dependen
private readonly WeakReference<TextBox> _textBox;
private readonly SerialDisposable _foregroundChanged = new SerialDisposable();

private static bool _issue9430WarnSingle = false;

public SinglelineTextBoxView(TextBox textBox)
{
_textBox = new WeakReference<TextBox>(textBox);
Expand All @@ -27,6 +33,26 @@ public SinglelineTextBoxView(TextBox textBox)
Initialize();
}

internal static SinglelineTextBoxView CreateSinglelineTextBoxView(TextBox textBox)
{
if (UIDevice.CurrentDevice.CheckSystemVersion(16, 0) && !FeatureConfiguration.TextBox.IOS16EnableSelectionSupport)
{
if (!_issue9430WarnSingle && typeof(SinglelineTextBoxView).Log().IsEnabled(LogLevel.Error))
{
_issue9430WarnSingle = true;
typeof(SinglelineTextBoxView).Log().Error($"TextBox selection events are disabled on iOS 16. See https://github.com/unoplatform/uno/issues/9430 for additional details.");
}

return new SinglelineTextBoxView(textBox);
}
else
{
return new SinglelineTextBoxViewWithSelection(textBox);
}
}

internal TextBox TextBox => _textBox.GetTarget();

private void OnEditingChanged(object sender, EventArgs e)
{
OnTextChanged();
Expand Down Expand Up @@ -198,6 +224,17 @@ public void RefreshFont()
{
UpdateFont();
}
}

/// <summary>
/// Workaround for https://github.com/unoplatform/uno/issues/9430
/// </summary>
internal partial class SinglelineTextBoxViewWithSelection : SinglelineTextBoxView
{
public SinglelineTextBoxViewWithSelection(TextBox textBox)
: base(textBox)
{
}

public override UITextRange SelectedTextRange
{
Expand All @@ -207,7 +244,7 @@ public override UITextRange SelectedTextRange
}
set
{
var textBox = _textBox.GetTarget();
var textBox = TextBox;

if (textBox != null && base.SelectedTextRange != value)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Controls/TextBox/TextBox.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void UpdateTextBoxView()
return;
}

_textBoxView = new SinglelineTextBoxView(this);
_textBoxView = SinglelineTextBoxView.CreateSinglelineTextBoxView(this);

_contentElement.Content = _textBoxView;
_textBoxView.SetTextNative(Text);
Expand Down

0 comments on commit c49c75d

Please sign in to comment.