Bug 58263 - Event and Delegate issue in ButtonRenderer
Summary: Event and Delegate issue in ButtonRenderer
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: iOS ()
Version: 2.3.5
Hardware: Macintosh Mac OS
: --- minor
Target Milestone: ---
Assignee: Jimmy [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2017-07-20 02:08 UTC by Eric Nusbaum
Modified: 2017-07-26 23:35 UTC (History)
3 users (show)

Tags: ac ios keyboard button event
Is this bug a regression?: ---
Last known good build:


Attachments
Button Custom Renderer to handle Keyboard (3.86 KB, application/octet-stream)
2017-07-20 02:08 UTC, Eric Nusbaum
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 58263 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Eric Nusbaum 2017-07-20 02:08:16 UTC
Created attachment 23673 [details]
Button Custom Renderer to handle Keyboard

This one took me a bit to debug, and I think I have an -OK- grasp on what is happening enough to actually write a bug on it. At least I think it's a bug... it might very well be my understanding of things that are off here.

My application is a Xamarin.Forms application which makes use of a custom Button control specifically for iOS, which is the topic of this defect.

I have a custom renderer for a Button (CustomButton_IOS.cs -- attached to this bug) where I'm setting Notification Events when the soft keyboard is displayed in IOS. I do this because I want my "Continue" button at the bottom of the form scrolled up above the soft keyboard while the user is entering text.

The use case is a user enters text into the Entry field and should be able to click the "Continue" button which makes use of the attache custom renderer.

What appears to be happening is when the "Hide" notification and delegate are invoked (UIKeyboard.WilHideNotification), if I move the button (by setting this.Center to a new position), the Xamarin.Forms assigned "Clicked" event will not fire. 

If I move the button relocation to a new thread (using Task.Factory) within the same delegate, the Xamarin.Forms "Clicked" event fill fire. 

I'm not sure if this is truly a threading issue or a timing issue. I suspect one of two things is happening:

1) Moving the button location within the delegate gets schwify with the Touch Events and perhaps "TouchUp" isn't invoked since the button is moved to a location that isn't currently being touched

-or-

2) Calling the button move in a new thread delays the move just long enough for the touch up event to fire before the button is moved.

Either way, this one burned me out.

Any help is appreciated!

-----

My system information is as follows:

Visual Studio Community 2017 for Mac (Preview)
Version 7.1 Preview (7.1 build 1281)
Installation UUID: 61ae6405-cfca-4fba-ba0e-f5bc6b8bd8eb
Runtime:
	Mono 5.2.0.209 (2017-04/3d531ba) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 502000209

NuGet
Version: 4.3.0.2418

.NET Core
Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
	1.1.1
	1.0.4
SDK: /usr/local/share/dotnet/sdk/1.0.3/Sdks
SDK Version: 1.0.3
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/msbuild/15.0/bin/Sdks

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

Apple Developer Tools
Xcode 8.3.3 (12175.1)
Build 8E3004b

Xamarin.iOS
Version: 10.12.0.14 (Visual Studio Community)
Hash: bf350ba5
Branch: d15-3
Build date: 2017-07-05 11:08:04-0400

Xamarin.Android
Version: 7.4.0.15 (Visual Studio Community)
Android SDK: /Users/ericnusbaum/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		6.0 (API level 23)

SDK Tools Version: 25.2.5
SDK Platform Tools Version: 25.0.6
SDK Build Tools Version: 25.0.3

Java SDK: /usr
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

Xamarin.Mac
Version: 3.6.0.13 (Visual Studio Community)

Xamarin Inspector
Version: 1.2.2
Hash: b71b035
Branch: d15-1
Build date: Fri, 21 Apr 2017 17:57:12 GMT

Build Information
Release ID: 701001281
Git revision: cc3abfe9b515ed0e209041e00d3ea239e8e33df9
Build date: 2017-07-10 21:15:50-04
Xamarin addins: 73710b74251e471826f2d9981d3a2bee6c4e78ad
Build lane: monodevelop-lion-d15-3

Operating System
Mac OS X 10.12.5
Darwin 16.6.0 Darwin Kernel Version 16.6.0
    Fri Apr 14 16:21:16 PDT 2017
    root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64
Comment 1 Jimmy [MSFT] 2017-07-20 23:14:50 UTC
Hi Eric,

This does seem to be a timing issue and is related to bug 45723. What's happening in this case is that touching the page while the keyboard is open will fire off a UITapGestureRecognizer we've added to automatically close the keyboard[1]. The touch event does still get passed to the Button, however since we're wired up to TouchUpInside event your guess about the Button being moved at the same time does seem to be correct. 

To avoid this you would need to add a delay like you've already done. If you like, you could simplify it by just adding a 1ms delay instead of creating a new thread. But ultimately this would be recommended approach in order to accomplish this right now.

There is a pull request for bug 45723 to add a platform-specific feature that allows you to set controls as first responder on iOS. This would prevent the touch gesture from going to the page so you would be responsible for closing the keyboard, but that would allow the Clicked event to be fired beforehand. 

I am going to keep this report open as confirmed so the team can review it further and determine if this behavior should be kept or changed. Thanks!

[1] https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.iOS/Renderers/PageRenderer.cs#L95
Comment 2 Eric Nusbaum 2017-07-21 02:01:10 UTC
Thanks Jimmy!

Would a workaround for this issue be remapping the TouchUpInside to TouchDownInside within the renderer? This would move it up the ole' event stack and possibly address this issue without any timing hackery.

I had started down this path at one point but wanted to file the defect as it seemed non-trivial, but in this case, perhaps the correct answer.

Thoughts?