React Native app with same code but different result for vertical margins in iOS and Android

Viewed 2077

I tested a simple render() on android (Galaxy S7) and iOS (iPhone S8+), and I get results that I don't understand.

  • The S7's height in dp's (Density-independent Pixels) is 640, while the iPhone 8 Plus height is 736 dp's, so I expected the distance between 'email' and 'password' to be somewhat smaller on the iPhone 8+, but not that tiny...
  • The 2nd issue is negative margins, that seem to behave differently on the two platforms. Is that what one should expect?

(And, yes, I know that I can set different margins on the two platforms, but I want to understand why the results are so different from my expectations...)

This is my code:

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

export class Login extends Component {

    render() {
      return (
          <View style={{ marginLeft: 100 }}>
                <View style={{ marginTop: 25 }}>
                    <TextInput
                        style={{ color: 'black', width: 260 }}
                        value='email'
                    />
                    <View style={{ marginTop: -10,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>

                <View style={{ marginTop: 5 }}>
                    <TextInput
                        style={{ color: 'black', width: 260 }}
                        value='password'
                    />
                    <View style={{ marginTop: -10,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>
          </View>
      );
    }
}

And this is how this code is displayed on an android Galaxy S7 emulator (left) and iPhone 8+ emulator.

android vs. iOS

2 Answers

I know this isn't your question, and i saw your profile and you're a react god yourself, and i respect that a lot haha

But my question is, why is the code like this, instead of being something like:

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

export class Login extends Component {

    render() {
      return (
          <View style={{ alignItems: 'center' }}>
                <TextInput
                    style={{color: 'black', width: 260, borderBottomWidth : 4,  marginTop: 25}}
                    value='email'
                />
                <TextInput
                    style={{color: 'black', width: 260, borderBottomWidth : 4, marginTop: 5}}
                    value='password'
                />
          </View>
      );
    }
}

Do this code works the same way?

[EDIT]

Also, maybe it's because some problems with the IOS top and bottom bar (On newer iphones, wich is not the case). So maybe the "Top" of the Android isn't the same "Top" as the IOS because Android apps doesn't overlaps the top bar like IOS do. So you can make a conditional check to change the IOS MarginTop value, like this:

import React, { Component } from 'react';
import { View, TextInput, Platorm } from 'react-native';

export class Login extends Component {

    render() {
      return (
          <View style={{ marginLeft: 100 }}>
                <View style={{ marginTop: Platform.OS == 'android' ? 25 : 35 }}>
                    <TextInput
                        style={{ color: 'black', width: 260 }}
                        value='email'
                    />
                    <View style={{ marginTop: Platform.OS == 'android' ? -10 : -5,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>

                <View style={{ marginTop: Platform.OS == 'android' ? 5 : 15}}>
                    <TextInput
                        style={{ color: 'black', width: 260 }}
                        value='password'
                    />
                    <View style={{ marginTop: Platform.OS == 'android' ? -10 : -5,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>
          </View>
      );
    }
}

I think this should work as fine.

The other answer and comment were good, but they didn't answer my question... :)
I asked why there is such a difference between the two platforms and not how it can be modified with platform specific values.

I found the answer here: react-native TextInput displays wrong when changing height on Android

quote: Android adds some default padding on top and bottom, you can reset them by adding paddingVertical: 0 to your element' style.

When specifying paddingVertical: 0, we get the expected results:

enter image description here

This is the updated code:
import React, { Component } from 'react';
import { View, TextInput } from 'react-native';

export class Login extends Component {

    render() {
      return (
          <View style={{ marginLeft: 100 }}>
                <View style={{ marginTop: 25 }}>
                    <TextInput
                        style={{ color: 'black', width: 260, paddingVertical: 0 }}
                        value='email'
                    />
                    <View style={{ marginTop: 0,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>

                <View style={{ marginTop: 15 }}>
                    <TextInput
                        style={{ color: 'black', width: 260, paddingVertical: 0 }}
                        value='password'
                    />
                    <View style={{ marginTop: 0,
                        borderBottomWidth: 1,
                        width: 200,
                        borderBottomColor: 'black' }} />
                </View>
          </View>
      );
    }
}
Related