From 5c59cbb5bd5664db5eb17f796dc3184043039868 Mon Sep 17 00:00:00 2001 From: Pavel Yakovlev Date: Mon, 7 May 2018 12:48:16 +0300 Subject: [PATCH] [iOS] Fixes App crash when clicking "undo", "cut", "delete" on Picker (#2567) Fixes #2465 * [iOS] Fixes App crash when clicking "undo", "cut", "delete" on Picker * fix a typo --- .../Renderers/PickerRenderer.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs index 05babb445..e9255a353 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/PickerRenderer.cs @@ -1,12 +1,28 @@ using System; +using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; +using Foundation; +using ObjCRuntime; using UIKit; using Xamarin.Forms.PlatformConfiguration.iOSSpecific; using RectangleF = CoreGraphics.CGRect; namespace Xamarin.Forms.Platform.iOS { + internal class ReadOnlyField : NoCaretField + { + readonly HashSet enableActions; + + public ReadOnlyField() { + string[] actions = { "copy:", "select:", "selectAll:" }; + enableActions = new HashSet (actions); + } + + public override bool CanPerform (Selector action, NSObject withSender) + => enableActions.Contains(action.Name); + } + public class PickerRenderer : ViewRenderer { UIPickerView _picker; @@ -25,7 +41,8 @@ namespace Xamarin.Forms.Platform.iOS { if (Control == null) { - var entry = new NoCaretField { BorderStyle = UITextBorderStyle.RoundedRect }; + // disabled cut, delete, and toggle actions because they can throw an unhandled native exception + var entry = new ReadOnlyField { BorderStyle = UITextBorderStyle.RoundedRect }; entry.EditingDidBegin += OnStarted; entry.EditingDidEnd += OnEnded; @@ -91,6 +108,8 @@ namespace Xamarin.Forms.Platform.iOS var selectedIndex = Element.SelectedIndex; var items = Element.Items; Control.Text = selectedIndex == -1 || items == null ? "" : items[selectedIndex]; + // Also clears the undo stack (undo/redo possible on iPads) + Control.UndoManager.RemoveAllActions(); } void OnEnded(object sender, EventArgs eventArgs)