facebook / react-native

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

Styling inconsistencies with IOS color decoding #20165

Closed rayj10 closed 6 years ago

rayj10 commented 6 years ago

So I have been developing my app mainly on Android, and everything was transferable to IOS so far until I noticed a tiny little inconsistencies on the styling as such: (look at the back and torch buttons, the 1px gap on the scanner screen, as well as the lighter shade of blue on user manual that's not supposed to be there)

enter image description here

enter image description here

The code looks like the following and nothing I tried has affected these weird gaps/discoloration:

Scanner page:

import React from 'react';
import {
    Alert,
    Linking,
    Text,
    View,
    StyleSheet
} from 'react-native';
import { BarCodeScanner, Permissions, Camera } from 'expo';

import { windowWidth, windowHeight, normalize } from '../theme/baseTheme';

const opacity = 'rgba(0, 0, 0, .6)';
const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    scanArea: {
        height: windowHeight - normalize(65),
        width: windowWidth
    },
    layerTop: {
        flex: 1,
        backgroundColor: opacity
    },
    layerCenter: {
        flex: 2,
        flexDirection: 'row'
    },
    layerLeft: {
        flex: 1,
        backgroundColor: opacity
    },
    focused: {
        flex: 10
    },
    layerRight: {
        flex: 1,
        backgroundColor: opacity
    },
    layerBottom: {
        flex: 1,
        backgroundColor: opacity
    },
});

export default class Scanner extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            hasCameraPermission: false,
            lastScan: null
        };
    }
    componentDidMount() {
        this._requestCameraPermission();
    }

    _requestCameraPermission = async () => {
        const { status } = await Permissions.askAsync(Permissions.CAMERA);
        this.setState({
            hasCameraPermission: status === 'granted',
        });
    };

    /**
     * Callback to be called by BarcodeScanner once it reads a compatible barcode, with param destructured
     * @param {Object} result: The result will be in the form of {type:String, data:String}
     */
    onSuccessRead = ({ type, data }) => {
        if (data !== this.state.lastScan) {
            this.setState({ lastScan: data })

            //Get a displayable version of the passed barcode type
            switch (type) {
                case BarCodeScanner.Constants.BarCodeType.aztec: type = "Aztec"; break;
                case BarCodeScanner.Constants.BarCodeType.codabar: type = "Codabar"; break;
                case BarCodeScanner.Constants.BarCodeType.code128: type = "Code128"; break;
                case BarCodeScanner.Constants.BarCodeType.code138: type = "Code138"; break;
                case BarCodeScanner.Constants.BarCodeType.code39: type = "Code39"; break;
                case BarCodeScanner.Constants.BarCodeType.code39mod43: type = "Code39mod43"; break;
                case BarCodeScanner.Constants.BarCodeType.code93: type = "Code93"; break;
                case BarCodeScanner.Constants.BarCodeType.datamatrix: type = "Datamatrix"; break;
                case BarCodeScanner.Constants.BarCodeType.ean13: type = "Ean13"; break;
                case BarCodeScanner.Constants.BarCodeType.ean8: type = "Ean8"; break;
                case BarCodeScanner.Constants.BarCodeType.interleaved2of5: type = "Interleaved2of5"; break;
                case BarCodeScanner.Constants.BarCodeType.itf14: type = "Itf14"; break;
                case BarCodeScanner.Constants.BarCodeType.maxicode: type = "Maxicode"; break;
                case BarCodeScanner.Constants.BarCodeType.pdf417: type = "Pdf417"; break;
                case BarCodeScanner.Constants.BarCodeType.qr: type = "QRCode"; break;
                case BarCodeScanner.Constants.BarCodeType.rss14: type = "Rss14"; break;
                case BarCodeScanner.Constants.BarCodeType.rssexpanded: type = "Rssexpanded"; break;
                case BarCodeScanner.Constants.BarCodeType.upc_a: type = "Upc_a"; break;
                case BarCodeScanner.Constants.BarCodeType.upc_e: type = "Upc_e"; break;
                case BarCodeScanner.Constants.BarCodeType.upc_ean: type = "Upc_ean"; break;
            }

            this.props.onRead(type, data, () => { this.setState({ lastScan: null }) }); //callback, what to do with the data on success read
        }
    }

    render() {
        return (
            <View style={styles.container}>
                {
                    this.state.hasCameraPermission === null ?
                        <Text>Requesting for camera permission</Text> :
                        this.state.hasCameraPermission === false ?
                            <Text style={{ color: '#fff' }}> Camera permission is not granted </Text> :

                            <BarCodeScanner
                                onBarCodeRead={this.onSuccessRead.bind(this)}
                                style={styles.scanArea}
                                autoFocus={Camera.Constants.AutoFocus.on}
                                focusDepth={1}
                                torchMode={this.props.torch}>

                                <View style={styles.layerTop} />
                                <View style={styles.layerCenter}>
                                    <View style={styles.layerLeft} />
                                    <View style={styles.focused} />
                                    <View style={styles.layerRight} />
                                </View>
                                <View style={styles.layerBottom} />
                            </BarCodeScanner>
                }
            </View>
        );
    }
}

User Manual page:

styles.js

import { StyleSheet } from 'react-native';
import { padding, color, fontSize, fontFamily, windowWidth, normalize } from '../../../theme/baseTheme';

const styles = StyleSheet.create({
  container: {
    flex: 1
  },

  headerContainer: {
    borderBottomWidth: 2,
    borderColor: color.blue,
    marginHorizontal: normalize(10),
    marginVertical: normalize(15),
  },

  headerText: {
    fontFamily: fontFamily.bold,
    fontSize: fontSize.large
  },

  accordionContainer: {
    marginVertical: normalize(10),
    marginHorizontal: normalize(10)
  },

  manualContainer: {
    flex: 1,
    marginVertical: normalize(10),
  },

  manualHeader: {
    height: normalize(110),
    backgroundColor: color.light_blue,
    borderTopRightRadius: normalize(20),
    borderTopLeftRadius: normalize(20),
    alignItems: 'center'
  },

  manualImage: {
    height: normalize(80),
    width: normalize(80),
    resizeMode: 'contain',
    marginVertical: normalize(15)
  },

  manualBody: {
    flex: 3,
    borderBottomRightRadius: normalize(20),
    borderBottomLeftRadius: normalize(20),
    backgroundColor: color.white
  },

  manualTitle: {
    fontFamily: fontFamily.bold,
    fontSize: fontSize.large,
    alignSelf: 'center',
    marginVertical: normalize(15)
  },

  manualContent: {
    fontFamily: fontFamily.regular,
    fontSize: fontSize.regular,
    textAlign: 'justify',
    marginBottom: normalize(15),
    marginHorizontal: normalize(15)
  },

  buttonContainer: {
    position: 'absolute',
    bottom: 0,    
    height: normalize(60),
    width: normalize(60),
    backgroundColor: 'rgba(0, 0, 0, .4)',
    borderTopEndRadius: normalize(10)
  },

  backButton: {
    position: 'absolute',
    bottom: 0, 
    height: normalize(57),
    width: normalize(57),
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(0, 0, 0, .5)',
    borderTopEndRadius: normalize(7)
  }
});

export default styles;

UserManual.js

class UserManual extends React.Component {
  constructor(props) {
    super(props);
  }

  /**
   * Map list of tabs into list of Objects containing a full card information of manual
   * @param {Array} list: Tab titles 
   */
  mapTabsToManuals(list) {
    return list.map(item => {
      let text = "Lorem ipsum dolor sit amet, cu verear facilisi vel, soleat menandri mnesarchum in sed. Ex nullam blandit sententiae vix. Cum simul euripidis eu, ea malis oporteat delicatissimi quo, eam in menandri consequat philosophia. Fuisset oporteat pri at, tollit nostrum fierent nec id, eum ad solum detracto. Ex vel verear quaerendum.\n\nMalorum quaerendum ea vim, mel movet partem persecuti et, cu iudico impetus persius sea. Eos falli suscipit accommodare cu. Eam id sanctus albucius, agam facilisi interpretaris ei qui. Usu tamquam maiestatis delicatissimi et. Quo id detraxit reprehendunt, ex his accommodare complectitur.\n\nAd his ferri utroque accusata. Id nam elit decore vivendum. Per solet iuvaret fierent et, diam idque at mea. Vix cu saepe vituperatoribus. Mea nostrud deleniti in. Prompta consequat voluptaria ne eam, no wisi augue vis.\n\nNo qui mollis singulis partiendo. Odio dolorum splendide ut sit, sea in vivendum mediocrem voluptatum, in vim ferri nostro discere. Vim soleat doctus mentitum ut, ut eos decore reprimique consectetuer. Idque constituto mei an, per ei debitis eligendi. Eum ea omnis atomorum aliquando, nam te offendit ocurreret, at mea nusquam docendi.\n\nPro ad probo corpora, vocent dolores mel id, pri assum erroribus no. Oratio tantas ne quo. Cu purto duis nam, ei vix facer moderatius, at sumo neglegentur per. Ea recteque electram eos, sea dicant nullam ex, eu indoctum referrentur eam.";
      let source = links.IDtoIcon(item['MenuID'], 'white');

      return {
        image: source,
        title: links.IDtoName(item['MenuID']),
        content: text
      }
    });
  }

  /**
   * Get a carousel of cards containing tabs of menu based on title
   * @param {Object} menu: Level 1 Menu to be created a carousel from 
   */
  getCarousel(menu) {
    let sliderWidth = windowWidth - 30;
    let itemWidth = sliderWidth - 60;

    return <Carousel
      data={this.mapTabsToManuals(menu['Children'])}
      renderItem={({ item, index }) => {
        return (
          <View style={styles.manualContainer}>
            <View style={styles.manualHeader}>
              <Image style={styles.manualImage} source={item.image} />
            </View>
            <View style={styles.manualBody}>
              <Text style={styles.manualTitle}>{item.title}</Text>
              <Text style={styles.manualContent}>{item.content}</Text>
            </View>
          </View>
        );
      }}
      sliderWidth={sliderWidth}
      itemWidth={itemWidth}
    />
  }

  render() {
    return (
      <View style={styles.container}>
        <ScrollView>
          <View style={styles.headerContainer}>
            <Text style={styles.headerText}>User Manual</Text>
          </View>
          {
            this.props.menuReceived ? this.props.menuList.map((item, key) => {
              if (item['MenuID'] !== links.ID.HELP)
                return (
                  <View style={styles.accordionContainer} key={key}>
                    <Accordion title={links.IDtoName(item['MenuID'])} body={this.getCarousel(item)} />
                  </View>)
            }) : null
          }
        </ScrollView>
        <View style={styles.buttonContainer}>
          <TouchableOpacity style={{ flex: 1 }} onPress={() => Actions.pop()}>
            <View style={styles.backButton}>
              <Icon name='action-undo' type='simple-line-icon' size={40} color='white' />
            </View>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

At first I thought it was my IOS sim that was erroneous in decoding the colors but when I tried it on my iphone it has the same problem...

Any clue or opinion would be greatly appreciated here :D

react-native-bot commented 6 years ago

We are automatically closing this issue because it does not appear to follow any of the provided issue templates.

Please make use of the bug report template to let us know about a reproducible bug or regression in the core React Native library.

If you'd like to start a discussion, check out https://discuss.reactjs.org or follow the discussion template.