xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Bug] [Shell] iOS UIKeyCommands don't work with Xamarin.Forms.Shell #6040

Closed baskren closed 5 years ago

baskren commented 5 years ago

Description

iOS UIKeyCommands don't work (in Custom PageRenderer) when used with Xamarin.Forms.Shell

Steps to Reproduce

  1. Clone, build and run demo project in iOS Simulator (or iOS device with Bluetooth hardware keyboard)
  2. Press arrow keys on hardware keyboard to verify app shows which arrow key is pressed
  3. Modify demo app's App.xamls.cs as follows:
        public App()
        {
            InitializeComponent();

            // The following works
            //MainPage = new NavigationPage(new MainPage());

            // ... and this works as well
            //MainPage = new MainPage();

            // ... but the following does not work
            MainPage = new MyShell();
        }
  1. build and run demo app.
  2. Press arrow keys on hardware keyboard and verify app no longer shows which key is pressed.

Expected Behavior

UIKeyCommand in a custom PageRenderer works no matter what kind of container page its Element is within. In other words, PageRenderer with UIKeyCommand works when it is the Xamarin.Forms.Application.Current.MainPage, a child of a NavigationPage, or a ShellItem.

Actual Behavior

UIKeyCommand in a custom PageRenderer does not work if Page is a ShellItem

Basic Information

Version 8.0.4 (build 0) Installation UUID: c3c61da2-4d87-4c39-b8d3-9fbf7e6af430 GTK+ 2.24.23 (Raleigh theme) Xamarin.Mac 5.6.0.2 (d16-0 / 040682909)

Package version: 518010003

=== Mono Framework MDK ===

Runtime: Mono 5.18.1.3 (2018-08/fdb26b0a445) (64-bit) Package version: 518010003

=== NuGet ===

Version: 4.8.2.5835

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet Runtime Versions: 2.1.9 2.1.8 2.1.7 2.1.6 2.1.2 2.1.1 2.0.5 2.0.0 1.1.1 1.0.4 SDK: /usr/local/share/dotnet/sdk/2.1.505/Sdks SDK Versions: 2.1.505 2.1.504 2.1.503 2.1.500 2.1.302 2.1.301 2.1.4 2.0.0 1.0.3 MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.18.1/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.6.9 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Updater ===

Version: 11

=== Xamarin.Android ===

Version: 9.2.3.0 (Visual Studio Enterprise) Android SDK: /Users/ben/Library/Developer/Xamarin/android-sdk-macosx Supported Android versions: 4.4 (API level 19) 5.0 (API level 21) 5.1 (API level 22) 7.0 (API level 24) 7.1 (API level 25) 8.0 (API level 26) 8.1 (API level 27)

SDK Tools Version: 26.1.1 SDK Platform Tools Version: 28.0.0 SDK Build Tools Version: 28.0.3

Build Information: Mono: mono/mono/2018-08-rc@5ac37ccd385 Java.Interop: xamarin/java.interop/d16-0@c987483 LibZipSharp: grendello/LibZipSharp/d16-1@44de300 LibZip: nih-at/libzip/rel-1-5-1@b95cf3f MXE: xamarin/mxe/xamarin@b9cbb535 ProGuard: xamarin/proguard/master@905836d SQLite: xamarin/sqlite/3.26.0@325e91a Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-0@0a7edd6

=== Microsoft Mobile OpenJDK ===

Java SDK: /Users/ben/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_8.0.25 1.8.0-25 Android Designer EPL code available here: https://github.com/xamarin/AndroidDesigner.EPL

=== Android Device Manager ===

Version: 1.2.0.14 Hash: 86df26f Branch: remotes/origin/d16-0 Build date: 2019-04-05 16:58:56 UTC

=== Xamarin Inspector ===

Version: 1.4.3 Hash: db27525 Branch: 1.4-release Build date: Mon, 09 Jul 2018 21:20:18 GMT Client compatibility: 1

=== Apple Developer Tools ===

Xcode 10.2.1 (14490.122) Build 10E1001

=== Xamarin.Mac ===

Version: 5.8.0.0 (Visual Studio Enterprise) Hash: 0aa84521 Branch: d16-0 Build date: 2019-04-02 16:01:19-0400

=== Xamarin.iOS ===

Version: 12.8.0.0 (Visual Studio Enterprise) Hash: 0aa84521 Branch: d16-0 Build date: 2019-04-02 16:01:19-0400

=== Xamarin Designer ===

Version: 4.17.4.418 Hash: 3d086e814 Branch: remotes/origin/d16-0 Build date: 2019-04-01 09:20:10 UTC

=== Build Information ===

Release ID: 800040000 Git revision: 09831ae7eef8ea58cdfad2e923c65a5bf70d27fd Build date: 2019-04-15 23:04:13+00 Build branch: master Xamarin extensions: 5efedb990d786142d3b54351c01ce867af7b7680

=== Operating System ===

Mac OS X 10.14.4 Darwin 18.5.0 Darwin Kernel Version 18.5.0 Mon Mar 11 20:40:32 PDT 2019 root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64

=== Enabled user installed extensions ===

Xamarin.Forms HotReload extension 1.1.0 AddinMaker 1.5.0 Cake Task Runner 0.1 Grunt Task Runner 0.1 Gulp Task Runner 0.1 MSBuild Editor 2.2.0 NPM Task Runner 1.4 NuGet Package Explorer 0.3.1 Open With 0.2 NuGet Package Management Extensions 0.17 Task Runner Explorer 0.1.1 Task Runners Bundle 0.1 TypeScript Task Runner 0.1 Delete bin obj folders 1.0


- Platform Target Frameworks: 
  - iOS:  iOS 9.0
  - Android: n/a
  - UWP:  n/a
- Android Support Library Version: n/a
- Nuget Packages: Xamarin.Forms 4.0.0.346134-pre9, Xamarin.Essentials 1.1.0
- Affected Devices: iOS Simulator, iOS devices

### Screenshots

n/a

### Reproduction Link

https://github.com/baskren/HardwareKey
kingces95 commented 5 years ago

@baskren Is there a reproduction of this issue without using a custom renderer? Custom renderers "void the warrenty" so to speak. If not, then please describe the deficiency in the existing renderer and we'll see if we can't add a feature to plug that hole.

baskren commented 5 years ago

In trying to understand why this is not an issue for standard Xamarin.Forms elements (ex: tab stops), I modified the demo app's shared code to include an Entry in the StackLayout. When the updated app starts, the behavior is still, unfortunately, the same - no feedback from the hardware keyboard (the custom renderer's UIKeyCommand) when the page is contained within a Shell.

However, the moment I either tabbed or tapped to the Entry, the feedback from the hardware keyboard started working! Examining the source for EntryRenderer:

https://github.com/xamarin/Xamarin.Forms/blob/334e23d7c6fe35a411af7eadfaa978ebcacf6a5f/Xamarin.Forms.Platform.iOS/ViewRenderer.cs#L262-L270

Was it possible that something was different about who was the first responder when using Xamarin.Forms.Shell? To test this hypothesis, I added the following to MainPageRenderer.cs:

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            BecomeFirstResponder();
        }

And it seems to address the issue.

Unfortunately, a search of Xamarin.Forms.Platform.iOS.Renderers.ShellRender.cs revealed nothing to indicate a difference in approach to assignment of FirstResponder. And likewise, a search of the entire repository for BecomeFirstResponder and ResignFirstResponder shed no light on the root cause as well.

This issue is not longer a blocker.