From a2401a9f6a4757fd2cf702afd589669eff37ed0a Mon Sep 17 00:00:00 2001 From: Kirill Lyubimov Date: Mon, 23 Aug 2021 18:03:02 +0400 Subject: [PATCH] Fix crashing on iOS < 14 if ClearButtonVisibility = WhileEditing in Entry (#14479 #14510) --- .../Renderers/EntryRenderer.cs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs index 51f235fb46f..069d994aff0 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs @@ -50,6 +50,8 @@ public abstract class EntryRendererBase : ViewRenderer Control?.ValueForKey(new NSString("clearButton")) as UIButton; + public EntryRendererBase() { } @@ -90,6 +92,8 @@ protected override void Dispose(bool disposing) Control.EditingDidEnd -= OnEditingEnded; Control.ShouldChangeCharacters -= ShouldChangeCharacters; _selectedTextRangeObserver?.Dispose(); + + ClearButton?.Layer?.RemoveObserver(this, new NSString("sublayers")); } } @@ -123,6 +127,8 @@ protected override void OnElementChanged(ElementChangedEventArgs e) textField.EditingDidEnd += OnEditingEnded; textField.ShouldChangeCharacters += ShouldChangeCharacters; _selectedTextRangeObserver = textField.AddObserver("selectedTextRange", NSKeyValueObservingOptions.New, UpdateCursorFromControl); + + ClearButton?.Layer.AddObserver(this, new NSString("sublayers"), NSKeyValueObservingOptions.New, IntPtr.Zero); } // When we set the control text, it triggers the UpdateCursorFromControl event, which updates CursorPosition and SelectionLength; @@ -154,6 +160,12 @@ protected override void OnElementChanged(ElementChangedEventArgs e) UpdateClearButtonVisibility(); } + public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context) + { + if (keyPath == new NSString("sublayers") && _defaultClearImage == null) + UpdateClearButtonVisibility(); + } + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Entry.PlaceholderProperty.PropertyName || e.PropertyName == Entry.PlaceholderColorProperty.PropertyName) @@ -564,24 +576,27 @@ void UpdateClearButtonVisibility() void UpdateClearButtonColor() { - if (Control.ValueForKey(new NSString("clearButton")) is UIButton clearButton) + if (ClearButton != null) { - clearButton.TintColor = Element.TextColor.ToUIColor(); - + ClearButton.TintColor = Element.TextColor.ToUIColor(); + if(_defaultClearImage == null) - _defaultClearImage = clearButton.ImageForState(UIControlState.Highlighted); + _defaultClearImage = ClearButton.ImageForState(UIControlState.Highlighted); + + if (_defaultClearImage == null) + return; if(Element.TextColor == Color.Default) { - clearButton.SetImage(_defaultClearImage, UIControlState.Normal); - clearButton.SetImage(_defaultClearImage, UIControlState.Highlighted); + ClearButton.SetImage(_defaultClearImage, UIControlState.Normal); + ClearButton.SetImage(_defaultClearImage, UIControlState.Highlighted); } else { var tintedClearImage = GetClearButtonTintImage(_defaultClearImage, Element.TextColor.ToUIColor()); - clearButton.SetImage(tintedClearImage, UIControlState.Normal); - clearButton.SetImage(tintedClearImage, UIControlState.Highlighted); + ClearButton.SetImage(tintedClearImage, UIControlState.Normal); + ClearButton.SetImage(tintedClearImage, UIControlState.Highlighted); } } }