Skip to content

Commit

Permalink
fix: Updated workaround for iOS 16 UITextInput.SelectedTextRange cr…
Browse files Browse the repository at this point in the history
…ashes

Pro: It does not break app compatibility, selection works

Con: This does not work _currently_ with the dynamic registrar [1] which is the default when building for iOS simulators. OTOH there's a workaround for that [2].

[1] Unless building with the iOS SDK for Xcode 14 (currently only previews) once xamarin/xamarin-macios#15712 is merged

[2] Adding `--registrar=static` to the simulator builds will fix this, sadly build times will be longer (so better use [1] asap)
  • Loading branch information
spouliot authored and jeromelaban committed Aug 31, 2022
1 parent c49c75d commit 448a56b
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 44 deletions.
9 changes: 0 additions & 9 deletions src/Uno.UI/FeatureConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,15 +375,6 @@ public static class TextBox
/// </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
49 changes: 15 additions & 34 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/SinglelineTextBoxView.iOS.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using CoreGraphics;
using ObjCRuntime;
using Uno.UI.DataBinding;
using Uno.UI.Views.Controls;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using UIKit;
using Uno.Extensions;
Expand All @@ -23,8 +25,6 @@ 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 @@ -33,24 +33,6 @@ 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)
Expand Down Expand Up @@ -224,31 +206,30 @@ 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)
{
}
/// <summary>
/// Workaround for https://github.com/unoplatform/uno/issues/9430
/// </summary>
[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSendSuper")]
static extern IntPtr IntPtr_objc_msgSendSuper(IntPtr receiver, IntPtr selector);

[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSendSuper")]
static extern void void_objc_msgSendSuper(IntPtr receiver, IntPtr selector, IntPtr arg);

public override UITextRange SelectedTextRange
[Export("selectedTextRange")]
public new IntPtr SelectedTextRange
{
get
{
return base.SelectedTextRange;
return IntPtr_objc_msgSendSuper(SuperHandle, Selector.GetHandle("selectedTextRange"));
}
set
{
var textBox = TextBox;

if (textBox != null && base.SelectedTextRange != value)
if (textBox != null && IntPtr_objc_msgSendSuper(SuperHandle, Selector.GetHandle("selectedTextRange")) != value)
{
base.SelectedTextRange = value;
void_objc_msgSendSuper(SuperHandle, Selector.GetHandle("setSelectedTextRange:"), value);
textBox.OnSelectionChanged();
}
}
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 = SinglelineTextBoxView.CreateSinglelineTextBoxView(this);
_textBoxView = new SinglelineTextBoxView(this);

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

0 comments on commit 448a56b

Please sign in to comment.