Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ios PasswordBox changed event when focus #19337

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public override bool ShouldChangeCharacters(UITextField textField, NSRange range
{
if (textField is SinglelineTextBoxView textBoxView)
{
if (_textBox.GetTarget() is not TextBox textBox)
if (_textBox.GetTarget() is not { } textBox)
{
return false;
}
Expand All @@ -50,7 +50,7 @@ public override bool ShouldChangeCharacters(UITextField textField, NSRange range
// When replacing text from pasting (multiple characters at once)
// we should only allow it (return true) when the new text length
// is lower or equal to the allowed length (TextBox.MaxLength)
var newLength = textBoxView.Text.Length + replacementString.Length - range.Length;
var newLength = textBoxView.Text?.Length + replacementString.Length - range.Length;
return newLength <= textBox.MaxLength;
};
}
Expand Down
59 changes: 41 additions & 18 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/SinglelineTextBoxView.iOS.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
#nullable enable
using System;
using System.Runtime.InteropServices;
using CoreGraphics;
using Foundation;
Expand All @@ -19,10 +20,10 @@ namespace Microsoft.UI.Xaml.Controls
{
public partial class SinglelineTextBoxView : UITextField, ITextBoxView, DependencyObject, IFontScalable
{
private SinglelineTextBoxDelegate _delegate;
private SinglelineTextBoxDelegate _delegate = null!;
private readonly WeakReference<TextBox> _textBox;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private SinglelineTextBoxDelegate _delegate = null!;
private SinglelineTextBoxDelegate _delegate;

and tag Initialize() with [MemberNotNull(nameof(_delegate))]

private Action _foregroundChanged;
private IDisposable _foregroundBrushChangedSubscription;
private Action? _foregroundChanged;
private IDisposable? _foregroundBrushChangedSubscription;

public SinglelineTextBoxView(TextBox textBox)
{
Expand All @@ -32,13 +33,13 @@ public SinglelineTextBoxView(TextBox textBox)
Initialize();
}

public override void Paste(NSObject sender) => HandlePaste(() => base.Paste(sender));
public override void Paste(NSObject? sender) => HandlePaste(() => base.Paste(sender));

public override void PasteAndGo(NSObject sender) => HandlePaste(() => base.PasteAndGo(sender));
public override void PasteAndGo(NSObject? sender) => HandlePaste(() => base.PasteAndGo(sender));

public override void PasteAndMatchStyle(NSObject sender) => HandlePaste(() => base.PasteAndMatchStyle(sender));
public override void PasteAndMatchStyle(NSObject? sender) => HandlePaste(() => base.PasteAndMatchStyle(sender));

public override void PasteAndSearch(NSObject sender) => HandlePaste(() => base.PasteAndSearch(sender));
public override void PasteAndSearch(NSObject? sender) => HandlePaste(() => base.PasteAndSearch(sender));

public override void Paste(NSItemProvider[] itemProviders) => HandlePaste(() => base.Paste(itemProviders));

Expand All @@ -54,7 +55,7 @@ private void HandlePaste(Action baseAction)

internal TextBox TextBox => _textBox.GetTarget();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
internal TextBox TextBox => _textBox.GetTarget();
internal TextBox? TextBox => _textBox.GetTarget();

public override string Text
public override string? Text
{
get => base.Text;
set
Expand All @@ -69,15 +70,14 @@ public override string Text
}
}

private void OnEditingChanged(object sender, EventArgs e)
private void OnEditingChanged(object? sender, EventArgs e)
{
OnTextChanged();
}

private void OnTextChanged()
{
var textBox = _textBox?.GetTarget();
if (textBox != null)
if (TextBox is { } textBox)
{
var text = textBox.ProcessTextInput(Text);
SetTextNative(text);
Expand All @@ -99,29 +99,40 @@ private void Initialize()

partial void OnLoadedPartial()
{
this.EditingChanged += OnEditingChanged;
this.EditingDidEnd += OnEditingChanged;
SubscribeEditingEvents();
}

partial void OnUnloadedPartial()
{
this.EditingChanged -= OnEditingChanged;
this.EditingDidEnd -= OnEditingChanged;
UnsubscribeEditingEvents();
}

//Forces the secure UITextField to maintain its current value upon regaining focus
public override bool BecomeFirstResponder()
{
var result = base.BecomeFirstResponder();

if (SecureTextEntry)
if (SecureTextEntry && !string.IsNullOrEmpty(Text))
{
UnsubscribeEditingEvents();

var text = Text;
Text = string.Empty;
UpdatePasswordText(string.Empty);
InsertText(text);
UpdatePasswordText(text);

SubscribeEditingEvents();
}

Comment on lines +115 to 125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldnt it be better to use a flag to guard the handlers, instead of un- and re-registering the events?

return result;

void UpdatePasswordText(string text)
{
if (TextBox is PasswordBox passwordBox)
{
passwordBox.Password = text;
}
}
}

public override CGSize SizeThatFits(CGSize size)
Expand Down Expand Up @@ -261,5 +272,17 @@ public void Select(int start, int length)
}
}
}

private void SubscribeEditingEvents()
{
EditingChanged += OnEditingChanged;
EditingDidEnd += OnEditingChanged;
}

private void UnsubscribeEditingEvents()
{
EditingChanged -= OnEditingChanged;
EditingDidEnd -= OnEditingChanged;
}
}
}
Loading