NativeViewHost is rendered in front of whole app

Hey guys,

I am trying to implement native date and time picker. I’ve found a nice project which does exactly what I need.
https://github.com/nekronos/FuseNativeControls provides both features and behaves as expected on iOS.

Unfortunately the android version is unstable and crashes the app when selecting dates.

Despite this, the NativeViewHost is rendered in front of the whole app, instead of the page I have assigned it to.

On iOS the Pickers respect the Layout and do not cover the navigation elements in my navigation bar. So I can at least open a side menu but cannot interact with it.
On Android the NativeViewHost is placed all over the whole screen.

I am using this implementation on a certain page I still have to navigate to. But nevertheless the Pickers are displayed on app startup.

<NativeViewHost>
    <Native.DatePicker ux:Name="datePicker">
        <JavaScript>
            var date = { year: 2018, month: 1, day: 13 };
            var minDate = { year: 2016, month: 1, day: 1 };
            var maxDate = { year: 2020, month: 1, day: 31 };

            datePicker.setDate(date);
            datePicker.setMaxDate(maxDate);
            datePicker.setMinDate(minDate);

            datePicker.CurrentDate.addSubscriber(function () {
                var d = datePicker.CurrentDate.value;
                console.log("Date changed: " + d["year"] + "-" + d["month"] + "-" + d["day"]);
            });

        </JavaScript>
    </Native.DatePicker>
</NativeViewHost>```

Does anyone know how to bind the NativeViewHost to a certain page, instead of being in front of everything?

Thank you in advance!

Hi!

NativeViewHost will always be its own layer on top of the graphics. However, you are free to put your entire app inside a native view host, this way you will get correct layering on everything:

 <App>
     <NativeViewHost>
          .. entire app goes here

This however doesn’t support all the effects and animations generally available in Fuse. We are actively working towards making this mode the default in all Fuse apps, so support will rapidly improve with the next few releases.

And of course, if you want to keep the structure you have today with just this specific component being in a NativeViewHost then you can still use navigation triggers & animators to ensure that the native content is hidden (collapsed or off-screen) when you’re not on the page it’s contained in.

you mean I have to keep it hidden in a Panel until needed, and then just animate in to my view? But wouldn’t it overlay everything when being revealed?

Yes, when it becomes visible it’ll overlay the regular components so it only works for scenarios / designs where that can make sense. (For instance: if you’re sliding in a page from the side)

You can also use the RenderToTexture property during the transition. This’ll allow you to layer the view as normal while you’re doing animations on it. When the view has then reached it’s rest state you can turn RenderToTexture off in order to interact with the component.

I just have nested the NativeViewHost in a 0 height StackPanel.

<StackPanel Height="0" >
	<NativeViewHost>
		<Native.DatePicker ux:Name="datePicker" />
		<Button Text="Reset date" Clicked="{reset}" />
	</NativeViewHost>
</StackPanel>

The NativeViewHost is then displayed just below the StackPanel.

Any other ideas how I can hide the NativeViewHost?

Edit: however this does not block any inputs in my sidemenu anymore. And the Picker is displayed on the respective page only. Feels like the right direction.

If something has an explicit size larger than its parent then it’ll typically outgrow the parent, which is what you’re seeing. :slight_smile:

What you should do if you just want the NativeViewHost to appear “from nothing” is to animate its Visibility property between “Hidden” and “Visible” states.
For instance, to use a WhileActive trigger which makes the NativeViewHost visible when the page it’s in is currently active:

			<DockPanel>
				<WhileActive>
					<Change nvh.Visibility="Visible"/>
				</WhileActive>
				<NativeViewHost ux:Name="nvh" Visibility="Hidden">
					<DockPanel>
						<WebView Url="http://fusetools.com"/>
						<Button Text="Reset date" Clicked="{reset}" Dock="Bottom" />
					</DockPanel>
				</NativeViewHost>
			</DockPanel>

Or you can just make sure that your navigation animations simply move the NativeViewHost off-screen.
For instance: this is what happens when you place it in a PageControl and swipe the page to the side.

Hi!

Author of https://github.com/nekronos/FuseNativeControls here. I read that you are experiencing issues on Android, please open an issue on the repo with a description of the problem. That would be very helpful! :slight_smile:

I can report that I got it running with hidden visibilities and toggling those visibilities. Its fine, thanks. The previously described crashes were most probably caused by the way they were overlayed over the app.

But I encountered a different problem on android devices when using the pickers.
I receive a multiple errors notification with this log:

LOG: Uno.Exception: java.lang.IllegalArgumentException: fromDate: Mon Jan 16 11:01:03 GMT+01:00 2017 does not precede toDate: Mon Jan 16 11:01:02 GMT+01:00 2017
       at Android.Base.JNI.TryGetException(Android.Base.Primitives.JNIEnvPtr,[string])
       at Android.Base.JNI.CheckException(Android.Base.Primitives.JNIEnvPtr,[string])
       at Android.Base.JNI.CheckException(Android.Base.Primitives.JNIEnvPtr)
       at Native.Android.DatePickerView.set_MinDate(Uno.Time.LocalDate)
       at Native.DatePickerBase.set_MinDate(Uno.Time.LocalDate)
       at Native.DatePickerBase.setMinDate(Fuse.Scripting.Context,Native.DatePickerBase,object[])
       at Fuse.Scripting.ScriptMethod`1.CallClosure.Run()
       at Fuse.UpdateManager.ProcessPostActionsImpl()
       at Fuse.UpdateManager.ProcessPostActions()
       at Fuse.UpdateManager.Update()
       at Outracks.Simulator.Application.OnUpdate()
       at Fuse.App.OnTick(object,Uno.Platform.TimerEventArgs)
       at Uno.Platform.Display.OnTick(Uno.Platform.TimerEventArgs)
       at Uno.Platform.AndroidDisplay.OnFrameCallback(double,double)
ERROR: java.lang.IllegalArgumentException: fromDate: Mon Jan 16 11:01:03 GMT+01:00 2017 does not precede toDate: Mon Jan 16 11:01:02 GMT+01:00 2017
    Uno.Exception occured.
       at Android.Base.JNI.TryGetException(Android.Base.Primitives.JNIEnvPtr,[string])
       at Android.Base.JNI.CheckException(Android.Base.Primitives.JNIEnvPtr,[string])
       at Android.Base.JNI.CheckException(Android.Base.Primitives.JNIEnvPtr)
       at Native.Android.DatePickerView.set_MinDate(Uno.Time.LocalDate)
       at Native.DatePickerBase.set_MinDate(Uno.Time.LocalDate)
       at Native.DatePickerBase.setMinDate(Fuse.Scripting.Context,Native.DatePickerBase,object[])
       at Fuse.Scripting.ScriptMethod`1.CallClosure.Run()
       at Fuse.UpdateManager.ProcessPostActionsImpl()
       at Fuse.UpdateManager.ProcessPostActions()
       at Fuse.UpdateManager.Update()
       at Outracks.Simulator.Application.OnUpdate()
       at Fuse.App.OnTick(object,Uno.Platform.TimerEventArgs)
       at Uno.Platform.Display.OnTick(Uno.Platform.TimerEventArgs)
       at Uno.Platform.AndroidDisplay.OnFrameCallback(double,double)```

However it works like a charm on a OnePlus 3 running 7.0 Nougat.

Lollipop devices with 5.1.1 are unable to use this pickers.

Great that you got it working!

Please report issues with the pickers themselves in the repo that Vegard mentioned. (https://github.com/nekronos/FuseNativeControls )