[ios] Get size of a View in React Native

Is it possible to get the size (width and height) of a certain view? For example, I have a view showing the progress:

<View ref='progressBar' style={{backgroundColor:'red',flex:this.state.progress}} /> 

I need to know the actual width of the view to align other views properly. Is this possible?

This question is related to ios react-native

The answer is


Maybe you can use measure:

measureProgressBar() {
    this.refs.welcome.measure(this.logProgressBarLayout);
},

logProgressBarLayout(ox, oy, width, height, px, py) {
  console.log("ox: " + ox);
  console.log("oy: " + oy);
  console.log("width: " + width);
  console.log("height: " + height);
  console.log("px: " + px);
  console.log("py: " + py);
}

As of React Native 0.4.2, View components have an onLayout prop. Pass in a function that takes an event object. The event's nativeEvent contains the view's layout.

<View onLayout={(event) => {
  var {x, y, width, height} = event.nativeEvent.layout;
}} />

The onLayout handler will also be invoked whenever the view is resized.

The main caveat is that the onLayout handler is first invoked one frame after your component has mounted, so you may want to hide your UI until you have computed your layout.


for me setting the Dimensions to use % is what worked for me width:'100%'


This is the only thing that worked for me:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image
} from 'react-native';

export default class Comp extends Component {

  find_dimesions(layout){
    const {x, y, width, height} = layout;
    console.warn(x);
    console.warn(y);
    console.warn(width);
    console.warn(height);
  }
  render() {
    return (
      <View onLayout={(event) => { this.find_dimesions(event.nativeEvent.layout) }} style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Double tap R on your keyboard to reload,{'\n'}
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('Comp', () => Comp);

Here is the code to get the Dimensions of the complete view of the device.

var windowSize = Dimensions.get("window");

Use it like this:

width=windowSize.width,heigth=windowSize.width/0.565


Basically if you want to set size and make it change then set it to state on layout like this:

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, View } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'yellow',
  },
  View1: {
    flex: 2,
    margin: 10,
    backgroundColor: 'red',
    elevation: 1,
  },
  View2: {
    position: 'absolute',
    backgroundColor: 'orange',
    zIndex: 3,
    elevation: 3,
  },
  View3: {
    flex: 3,
    backgroundColor: 'green',
    elevation: 2,
  },
  Text: {
    fontSize: 25,
    margin: 20,
    color: 'white',
  },
});

class Example extends Component {

  constructor(props) {
    super(props);

    this.state = {
      view2LayoutProps: {
        left: 0,
        top: 0,
        width: 50,
        height: 50,
      }
    };
  }

  onLayout(event) {
    const {x, y, height, width} = event.nativeEvent.layout;
    const newHeight = this.state.view2LayoutProps.height + 1;
    const newLayout = {
        height: newHeight ,
        width: width,
        left: x,
        top: y,
      };

    this.setState({ view2LayoutProps: newLayout });
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.View1}>
          <Text>{this.state.view2LayoutProps.height}</Text>
        </View>
        <View onLayout={(event) => this.onLayout(event)} 
              style={[styles.View2, this.state.view2LayoutProps]} />
        <View style={styles.View3} />
      </View>
    );
  }

}


AppRegistry.registerComponent(Example);

You can create many more variation of how it should be modified, by using this in another component which has Another view as wrapper and create an onResponderRelease callback, which could pass the touch event location into the state, which could be then passed to child component as property, which could override onLayout updated state, by placing {[styles.View2, this.state.view2LayoutProps, this.props.touchEventTopLeft]} and so on.


You can directly use the Dimensions module and calc your views sizes. Actually, Dimensions give to you the main window sizes.

import { Dimensions } from 'Dimensions';

Dimensions.get('window').height;
Dimensions.get('window').width;

Hope to help you!

Update: Today using native StyleSheet with Flex arranging on your views help to write clean code with elegant layout solutions in wide cases instead computing your view sizes...

Although building a custom grid components, which responds to main window resize events, could produce a good solution in simple widget components