React native rotation transformations break flex box layout

4.9k views Asked by At

I want to make a slider vertical on ios. I have a component that looks like this, the text labels are just for visualisation

export class VerticalSlider extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Hello</Text>
        <Slider
          maximumValue={100}
          minimumValue={0}
          value={50}
          minimumTrackTintColor="black"
          style={{
            transform: [{ rotate: '90deg' }]
          }}
        />
        <Text>Hello</Text>
      </View>

    )
  }
}

This is how it looks in my simulator

enter image description here

It looks like flex box lays out the components before the rotation, then it gets rotated 90 degrees and it overlaps with the text labels above and below. I would expect the top of the slider to be at the bottom of the first label and the second label to be pushed down.

Is there something i can do to fix this?

Here are my versions:

"dependencies": {
    "expo": "^29.0.0",
    "react": "16.3.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz"
  }
1

There are 1 answers

2
TBouder On BEST ANSWER

If I undestand it correctly, you want something like this, right (don't pay attention to the title and the cross) ?

(https://i.stack.imgur.com/AIVjm.jpg)

If it's what you want, you just have to wrap your components in a view with a flex:

<View style={{flex: 1}}>
    <View style={{flex: 1}}>
        <Text>Hello</Text>
    </View>
    <View style={{flex: 1}}>
        <Slider
            maximumValue={100}
            minimumValue={0}
            value={50}
            minimumTrackTintColor="black"
            style={{transform: [{rotate: '90deg'}]}} />
    </View>
    <View style={{flex: 1}}>
        <Text>Hello</Text>
    </View>
</View>

Edit (explanation) :

A flexbox is basically an area. In this area, all the Subarea will take some space according to their flex property.

If you have a 3 sub - area where the flex property is set to 1, the 3 will take the space space:

[ 1 | 2 | 3 ]

If you have a 3 sub - area where the flex property is set to 1, 1 and 2, the total area will have a size of 4 flex:

[ 1 | 2 | 3 3 ]

I don't know if it's clear, but you can check this link. It's basically the same with React Native, except that you don't need to display your view as Flex :)

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

In your code, even if your <View> is a flexbox with a flex set to 1, your <Text> and <Slider> are not flexible components, so there is nothing saying that they have to take 1/3 (each) of the total space. By wrapping them in a View style={{flex: 1}}> we are just setting this and ta-da