所以我一直主要在Android上开发我的应用程序,到目前为止,所有内容都可以转移到IOS,直到我注意到样式上的微小不一致之处为止((查看后退和手电筒按钮,扫描仪上的1px间隙)屏幕,以及用户手册上不应有的浅蓝色)
代码如下所示,我尝试过的所有方法均未影响这些怪异的间隙/变色:
扫描仪页面:
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>
);
}
}
用户手册页面:
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>
);
}
}
起初我以为是IOS sim卡在解码颜色时是错误的,但是当我在iphone上尝试时,它也遇到了同样的问题...