Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can onLayout also provide the page position, like measure does? #10556

Closed
josvos opened this issue Oct 26, 2016 · 8 comments
Closed

Can onLayout also provide the page position, like measure does? #10556

josvos opened this issue Oct 26, 2016 · 8 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@josvos
Copy link

josvos commented Oct 26, 2016

Description

The onLayout callback now provides in its layout data the same information as the measure (NativeMethodsMixin) callback does, except for the missing absolute page position. Is there a technical reason for this, or can these 2 values also be included in the onLayout data?

I'm now calling measure (i.e. triggering the callback) in the onLayout callback, in order to know when measure() can provide (update) information, but this seems to be double work.

@lacker
Copy link
Contributor

lacker commented Nov 30, 2016

I don't think there's a technical reason for this, it's more that it's bad form to use the absolute page position all the time. It seems like you have a valid workaround so I am going to close this issue.

@lacker lacker closed this as completed Nov 30, 2016
@scally
Copy link

scally commented Jan 25, 2017

So, there's a workaround for this, but it's really awkward -- you need to save a child view as a ref, and then use that ref in a callback in another callback in onLayout.

There are legitimate use cases for absolute page positioning, one of which is drag/drop; if you want to know if one component has been dropped onto another when the two don't share a common immediate parent.

If there's no technical limitation preventing this from being surfaced as a param to onLayout (or on another event handler) then could we re-open this issue?

@scally
Copy link

scally commented Jan 25, 2017

the workaround looks like this, fwiw:

render() {
    return (
      <View
        ref={ref => this.view = ref}
        onLayout={() => this.saveLayout()}
        >
  )
}

// later....

saveLayout() {
  this.view.measureInWindow((x, y, width, height) => {
    // do a thing with the layout...
  }
}

@mattread90
Copy link

I'm also after the pageX/pageY for the purposes of drag and drop, so having to resort to .measure().

On a slightly different but related note, my .measure() call is returning inconsistent values when my view is first mounted after navigating to the scene. The pageX value is being given as either 0 or 374.5, which I'm guessing is due to the fact that the scene is sliding in from the right and the onLayout callback is being fired at different times during this process.

@Ashoat
Copy link
Contributor

Ashoat commented Sep 15, 2017

A good reason that pageX/pageY are needed is that PanResponder's relative positioning info is double broken (#12591, #15290). The first issue is fixed in upcoming release [email protected], but the second has unfortunately not be debugged yet.

Currently, any components that rely on panning behavior are forced to do absolute comparisons, and this issue makes that really hard by forcing people to use a measure() nested inside an onLayout to even get at the absolute data they need.

@HideyaSwider
Copy link

I am also in need of these properties. Has anyone gotten anywhere?

@necolas
Copy link
Contributor

necolas commented Feb 13, 2018

FWIW, I was also hoping onLayout would provide the equivalent data to either web's getBoundingClientRect or web's ResizeObserver.

@techrah
Copy link

techrah commented Mar 20, 2018

I'm currently using RN: 0.52.0. Here is my "2¢" on this topic.

The onLayout callback now provides in its layout data the same information as the measure (NativeMethodsMixin) callback does, except for the missing absolute page position.

This is not the case for me! I have a layout similar to the following:

<View style={{ flex: 1 }}>
  <NavBar />
  <View style={{ flex: 1 }}>
    <TabBar />
    <View style={{ flex: 1 }} onLayout={ ... } ref={ ... }>
      {content}
    </View>
  </View>
</View>

So, I'm interested in getting the y coordinate of the innermost View relative to the screen. In onLayout, if I grab nativeEvent.layout, I get

{ height: 448, width: 360, x: 0, y: 102 }

If I also call measure on that same View, I get

{ height: 448, width: 360, x: 0, y: 0, pageX: 0, pageY: 192 }

Notice that y goes from 102 to 0. Meanwhile, its parent View has a layout of

{ height: 550, width: 360, x: 0, y: 90 }

Notice the y of 102 plus the y of 90 is now equal to pageY of 192, which incidentally is the actual number that I'm interested in (and is the position relative to the screen).

After this, I do not get any further onLayout callbacks, so I assume these are the final values.

Now, according to the docs:

Note that these measurements are not available until after the rendering has been completed in native. If you need the measurements as soon as possible, consider using the onLayout prop instead.

This seems to imply that they are the same... and I would rather get the measurements from onLayout since for my use case, calling measure and waiting for the callback takes too long.

Also, x and y as supplied by onLayout seems to be different from x and y as returned by measure and the docs do not give any details. I don't think I've ever received a non-zero x or y value from measure. I read somewhere that they are the coords relative to the frame but not sure what that means or in what situation I'd ever get a non-zero value. This is different from onLayout in which I was receiving non-zero y values.

So, my conclusion is that they are not the same, onLayout gives you a position relative to its parent, measure gives you absolute position (relative to screen) but you'd have to use the values of pageX and pageY instead of x and y ... and also suffer though the extra delay before you get your callback.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 19, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

9 participants