facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.01k stars 24.18k forks source link

Question: Is it possible to get the screen position of an element / component? #1374

Closed MossP closed 9 years ago

MossP commented 9 years ago

use case: I would like to add a small popUp menu at the location of a button on the page. THe button would be inside a list view though so isn't in a fixed position.

Thanks, and keep up the good work! :) :+1:

JohnyDays commented 9 years ago

I believe what you are looking for is


var RCTUIManager = require('NativeModules').UIManager;
//The following code executes inside one of your component's methods, post render
var view = this.refs['ref']; // Where view is a ref obtained through <View ref='ref'/>
var handle = React.findNodeHandle(view); 
RCTUIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
   //Do stuff with the values
})
MossP commented 9 years ago

I believe you are right. Thank you :)

bakso commented 9 years ago

But how to add the popular menu dynamic?

JohnyDays commented 9 years ago

I'm sorry, I'm afraid I didn't understand the question. You want to add a menu on the position of an element?

MossP commented 9 years ago

Hi @iostalk. I am implementing the menu by using @brentvatne's modal plugin then passing a complete collection of stylds into it (take a look at the modalstyle included in the the source).. you can then pass in the screen coordinates (derived from @johnydays code) that you'd like the modal window to show based on the size of your modal / touchable object.

anshul-kai commented 7 years ago

The solution to use UIManager is no longer working on Android with React Native 0.42.0

wasa4587 commented 7 years ago

@a-koka you can do it this way

              <View
                ref="Marker"
                onLayout={({nativeEvent}) => {
                  this.refs.Marker.measure((x, y, width, height, pageX, pageY) => {
                    console.log(x, y, width, height, pageX, pageY);
                  })
                }}
              >

or this way


              <View
                ref="Marker"
                onLayout={({nativeEvent}) => {
                  var view = this.refs['Marker'];
                  var handle = findNodeHandle(view);
                  UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
                    console.log(x, y, width, height, pageX, pageY);
                  })
                }}
              >
anshul-kai commented 7 years ago

onLayout is a good solution but not ideal for use cases where several layout changes occur thus causing several callbacks. My issue got resolved by adding the collapsible={false} prop to the views being measured.

Thanks to hey99xx for his help in https://github.com/facebook/react-native/issues/12966

Collapsable property is explained at https://facebook.github.io/react-native/docs/view.html#collapsable

Views that are only used to layout their children or otherwise don't draw anything may be automatically removed from the native hierarchy as an optimization. Set this property to false to disable this optimization and ensure that this View exists in the native view hierarchy.

However, some of UIManager functions such as measure expect to find a native view; and when it can't it returns undefined values instead of throwing an error. Really it would be better to throw an error. React unfortunately is not intelligent to know you would be measuring the view in the first place.

rajsuvariya commented 7 years ago

In my case, I need to measure the x and y coordinate on the click of an element which is inside a scroll view. So it gives me different px and py everytime I click on the element. also, the value differs based on the scrolling

gitlovenotwar commented 7 years ago

@rajsuvariya did you able to get the position of an element even inside a scrollview?

rajsuvariya commented 7 years ago

@gitlovenotwar No I was not able to get the position inside scroll view. But I had only one component inside scrollview so I removed scrollview and now I have only listview which gives me exact position of elemtn

ghost commented 6 years ago

@JohnyDays how can i get the position of cursor in ScrollView containing TextInput?