Instawork / hyperview

Server-driven mobile apps with React Native
https://hyperview.org
MIT License
1.26k stars 66 forks source link

`trigger="visible"` behaviour is different on iOS than on Android when navigating screens using react-navigation #780

Open Charles-Johnson opened 10 months ago

Charles-Johnson commented 10 months ago

The VisibilityDetectingView component triggers actions when the screen that the hyperview component is in comes back into focus on an Android device but on iOS no actions are triggered when the screen comes back into focus.

After adding console.log(arguments); to the onMeasure method, when navigating away from the screen I had 5 views with trigger="visible",I observed the output on Android:

[0, 0, 360, 8, 0, 644.3333129882812]
[0, 0, 360, 288, 0, 781.6666870117188]
[0, 0, 312, 146.6666717529297, 24, 497.6666564941406]
[0, 0, 360, 1873.6666259765625, 0, 1069.6666259765625]
[0, 0, 360, 248, 0, 211.3333282470703]
[]
[]
[]
[]
[]

and on iOS:

[0, 37, 366, 127.66668701171875, 24, 462]
[0, 545.6666870117188, 414, 8, 0, 589.6666870117188]
[0, 638.6666870117188, 414, 288, 0, 682.6666870117188]
[0, 926.6666870117188, 414, 1869, 0, 970.6666870117188]
[0, 136, 414, 245, 0, 180]
[0, 37, 366, 127.66668701171875, 24, 462]
[0, 545.6666870117188, 414, 8, 0, 589.6666870117188]
[0, 638.6666870117188, 414, 288, 0, 682.6666870117188]
[0, 926.6666870117188, 414, 1869, 0, 970.6666870117188]
[0, 136, 414, 245, 0, 180]

So it looks like this.view.measure calls the callback (this.onMeasure) without any arguments on Android when views aren't in focus but does provide arguments for iOS regardless of whether the screen is in focus.

I'm not sure whether this is a bug in react-native or react-navigation or whether hyperview should handle this inconsistency.

I'm also not sure whether navigation actions should affect the visible trigger or whether a separate trigger should be implemented for navigation focus events.

In order to unblock my work, in my fork of this library, I'm going to try to add an event listener in the VisibilityDetectingView for focus events: https://reactnavigation.org/docs/function-after-focusing-screen/#triggering-an-action-with-a-focus-event-listener

adamstep commented 10 months ago

@flochtililoch , any insights on desired behavior here or other approaches with the new navigation system (focus/blur events)?

flochtililoch commented 10 months ago

I would think the visible trigger should only trigger when the element is actually visible on screen. If an event causes an unfocused screen to reload, the elements that are in the unfocused view-pane should not trigger the visible behavior until their screen is focused again. We can rely on the focus/blur event on the new navigation system, but we could probably amend the visible handler to behave correctly for unfocused screens.

Charles-Johnson commented 8 months ago

I ended up not using the navigation focus event listener because it actually caused the hyperview screen to go blank if you navigate to a hyperview screen and immediately scroll down. I instead explicitly triggered events to update elements with trigger="on-event" and, in my fork, prevented the visibility action from being triggered when navigating screen on Android so that it is consistent with iOS