1

I am using the React Native PanResponder class to allow for drag and drop if elements of the screen.

What I have discovered is that the onLayout is not returning the x absolute positions, it's being affected by its parent views and is returning weird results.

For example the current view has 3 columns and the onLayout resides in the middle column. It is returning it's x value as 146.5. Which is not the absolute position.

How would I get the absolute position of the element if it resides in multiple parent views?

// Omitted some code for clarity

const dropZoneValues = React.useRef(null);

const pan = React.useRef(new Animated.ValueXY());

const setDropZoneValues = React.useCallback((event) =>
{
    dropZoneValues.current = event.nativeEvent.layout;

}, []);



return (
    <Main background={bg} showHeader={false}>


        <Row rowStyles={{
            textAlign: 'center', marginLeft: 50, marginRight: 50,
            alignSelf: 'center',
            alignItems: 'center',
            textAlignVertical: 'center',
            justifyContent: 'center',
        }}>

            <Col xs={4} sm={4} md={4} lg={4}>
            </Col>
            <Col xs={4} sm={4} md={4} lg={4}>

                <View
                    onLayout={setDropZoneValues}
                    style={styles.dropZone}>
                    <Text style={styles.text}>Drop me here!</Text>
                </View>

                {renderDraggable()}

            </Col>

            <Col xs={4} sm={4} md={4} lg={4}>
            </Col>

        </Row>

    </Main>

);

const styles = StyleSheet.create({
    mainContainer: {
        flex: 1,
        padding: 20,
        flexDirection: 'column',
    },
    dropZone: {
        height: 100,
        backgroundColor: '#2c3e50',
        width: 100,
        alignSelf: 'center',
        alignItems: 'center',
        justifyContent: 'center',
        position: 'absolute',
    },
    text: {
        marginTop: 25,
        marginLeft: 5,
        marginRight: 5,
        textAlign: 'center',
        color: '#fff'
    },
    draggableContainer: {
        zIndex: 99999
    },
    circle: {
        backgroundColor: '#1abc9c',
        width: 80,
        height: 80,
        borderRadius: CIRCLE_RADIUS,
        zIndex: 99999,
        position: 'absolute'
    }

});
user3574492
  • 6,225
  • 9
  • 52
  • 105
  • Does this answer your question? [React Native: Getting the position of an element](https://stackoverflow.com/questions/30096038/react-native-getting-the-position-of-an-element) – Abe Aug 11 '22 at 04:50

1 Answers1

0

onLayout returns positions relative to parents. You can instead use event.target.measure within the onLayout callback to find the absolute position (though note this is marginally worse for performance).

<MyComponent
  onLayout={(event) => {
    event.target.measure(
      (x, y, width, height, pageX, pageY) => {
        doSomethingWithAbsolutePosition({
          x: pageX, 
          y: pageY,
        });
      },
    );
  }}
/>

(hat tip to https://stackoverflow.com/a/64882955/842506)

owencm
  • 8,384
  • 6
  • 38
  • 54