mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Updates from Tue Mar 10
- [ReactNative] Make tests run on TravisCI | Alex Kotliarskyi - [Relay] Update Relay + ES6 class containers | Christoph Pojer - [React Native] Add RCTAdSupport.xcodeproj | Alexsander Akers - [ReactNative][Android] Fix after a new React version was downstreamed | Philipp von Weitershausen - [React Native] Add preliminary animation API | Alex Akers - [ReactKit] Create test for OSS ReactKit | Alex Kotliarskyi - [React Native][Device ID][wip] implement most basic js access | Alex Akers - [ReactNative] OSS Picker | Spencer Ahrens - [ReactNative] Fix typo in RCTUIManager | Tadeu Zagallo - [ReactNative] Fix GeoLocation files letter case | Tadeu Zagallo - Unified the method signature for addUIBlock: to further simplify porting ViewManagers | Nick Lockwood - [ReactNative] Oss GeoMap | Tadeu Zagallo - [ReactNative] OSS CameraRoll | Tadeu Zagallo - [ReactNative] allowLossyConversion on NSString->NSData conversion | Andrew Rasmussen - [React Native][RFC] Print __DEV__ value on app start | Alex Kotliarskyi
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule AdSupportIOSExample
|
||||
*/
|
||||
/* eslint no-console: 0 */
|
||||
'use strict';
|
||||
|
||||
var AdSupportIOS = require('AdSupportIOS');
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
exports.framework = 'React';
|
||||
exports.title = 'Advertising ID';
|
||||
exports.description = 'Example of using the ad support API.';
|
||||
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Ad Support IOS',
|
||||
render: function() {
|
||||
return <AdSupportIOSExample />;
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
var AdSupportIOSExample = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
deviceID: 'No IDFA yet',
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
AdSupportIOS.getAdvertisingId(
|
||||
this._onSuccess,
|
||||
this._onFailure
|
||||
);
|
||||
},
|
||||
|
||||
_onSuccess: function(deviceID) {
|
||||
this.setState({
|
||||
'deviceID': deviceID,
|
||||
});
|
||||
},
|
||||
|
||||
_onFailure: function(e) {
|
||||
this.setState({
|
||||
'deviceID': 'Error!',
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text>
|
||||
<Text style={styles.title}>Advertising ID: </Text>
|
||||
{JSON.stringify(this.state.deviceID)}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
title: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
@@ -20,7 +20,7 @@
|
||||
//
|
||||
// To run on device, change `localhost` to the IP address of your computer, and make sure your computer and
|
||||
// iOS device are on the same Wi-Fi network.
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.includeRequire.runModule.bundle"];
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.includeRequire.runModule.bundle?dev=true"];
|
||||
|
||||
// OPTION 2
|
||||
// Load from pre-bundled file on disk. To re-generate the static bundle, run
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule CameraRollExample
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
CameraRoll,
|
||||
Image,
|
||||
Slider,
|
||||
StyleSheet,
|
||||
SwitchIOS,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var CameraRollView = require('./CameraRollView.ios');
|
||||
|
||||
var CAMERA_ROLL_VIEW = 'camera_roll_view';
|
||||
|
||||
var CameraRollExample = React.createClass({
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
groupTypes: 'SavedPhotos',
|
||||
sliderValue: 1,
|
||||
bigImages: true,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<SwitchIOS
|
||||
onValueChange={this._onSwitchChange}
|
||||
value={this.state.bigImages} />
|
||||
<Text>{(this.state.bigImages ? 'Big' : 'Small') + ' Images'}</Text>
|
||||
<Slider
|
||||
value={this.state.sliderValue}
|
||||
onValueChange={this._onSliderChange}
|
||||
/>
|
||||
<Text>{'Group Type: ' + this.state.groupTypes}</Text>
|
||||
<CameraRollView
|
||||
ref={CAMERA_ROLL_VIEW}
|
||||
batchSize={5}
|
||||
groupTypes={this.state.groupTypes}
|
||||
renderImage={this._renderImage}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_renderImage(asset) {
|
||||
var imageSize = this.state.bigImages ? 150 : 75;
|
||||
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
|
||||
var location = asset.node.location.longitude ?
|
||||
JSON.stringify(asset.node.location) : 'Unknown location';
|
||||
return (
|
||||
<View key={asset} style={styles.row}>
|
||||
<Image
|
||||
source={asset.node.image}
|
||||
style={imageStyle}
|
||||
/>
|
||||
<View style={styles.info}>
|
||||
<Text style={styles.url}>{asset.node.image.uri}</Text>
|
||||
<Text>{location}</Text>
|
||||
<Text>{asset.node.group_name}</Text>
|
||||
<Text>{new Date(asset.node.timestamp).toString()}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_onSliderChange(value) {
|
||||
var options = CameraRoll.GroupTypesOptions;
|
||||
var index = Math.floor(value * options.length * 0.99);
|
||||
var groupTypes = options[index];
|
||||
if (groupTypes !== this.state.groupTypes) {
|
||||
this.setState({groupTypes: groupTypes});
|
||||
}
|
||||
},
|
||||
|
||||
_onSwitchChange(value) {
|
||||
this.refs[CAMERA_ROLL_VIEW].rendererChanged();
|
||||
this.setState({ bigImages: value });
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
},
|
||||
url: {
|
||||
fontSize: 9,
|
||||
marginBottom: 14,
|
||||
},
|
||||
image: {
|
||||
margin: 4,
|
||||
},
|
||||
info: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<CameraRollView>';
|
||||
exports.description = 'Example component that uses CameraRoll to list user\'s photos';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Photos',
|
||||
render() { return <CameraRollExample />; }
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule CameraRollView
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActivityIndicatorIOS,
|
||||
CameraRoll,
|
||||
Image,
|
||||
ListView,
|
||||
ListViewDataSource,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var groupByEveryN = require('groupByEveryN');
|
||||
var logError = require('logError');
|
||||
|
||||
var propTypes = {
|
||||
/**
|
||||
* The group where the photos will be fetched from. Possible
|
||||
* values are 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream'
|
||||
* and SavedPhotos.
|
||||
*/
|
||||
groupTypes: React.PropTypes.oneOf([
|
||||
'Album',
|
||||
'All',
|
||||
'Event',
|
||||
'Faces',
|
||||
'Library',
|
||||
'PhotoStream',
|
||||
'SavedPhotos',
|
||||
]),
|
||||
|
||||
/**
|
||||
* Number of images that will be fetched in one page.
|
||||
*/
|
||||
batchSize: React.PropTypes.number,
|
||||
|
||||
/**
|
||||
* A function that takes a single image as a parameter and renders it.
|
||||
*/
|
||||
renderImage: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* imagesPerRow: Number of images to be shown in each row.
|
||||
*/
|
||||
imagesPerRow: React.PropTypes.number,
|
||||
};
|
||||
|
||||
var CameraRollView = React.createClass({
|
||||
propTypes: propTypes,
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
groupTypes: 'SavedPhotos',
|
||||
batchSize: 5,
|
||||
imagesPerRow: 1,
|
||||
renderImage: function(asset) {
|
||||
var imageSize = 150;
|
||||
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
|
||||
return (
|
||||
<Image
|
||||
source={asset.node.image}
|
||||
style={imageStyle}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged});
|
||||
|
||||
return {
|
||||
assets: [],
|
||||
groupTypes: this.props.groupTypes,
|
||||
lastCursor: null,
|
||||
noMore: false,
|
||||
loadingMore: false,
|
||||
dataSource: ds,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* This should be called when the image renderer is changed to tell the
|
||||
* component to re-render its assets.
|
||||
*/
|
||||
rendererChanged: function() {
|
||||
var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged});
|
||||
this.state.dataSource = ds.cloneWithRows(
|
||||
groupByEveryN(this.state.assets, this.props.imagesPerRow)
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (this.props.groupTypes !== nextProps.groupTypes) {
|
||||
this.fetch(true);
|
||||
}
|
||||
},
|
||||
|
||||
_fetch: function(clear) {
|
||||
if (clear) {
|
||||
this.setState(this.getInitialState(), this.fetch);
|
||||
return;
|
||||
}
|
||||
|
||||
var fetchParams = {
|
||||
first: this.props.batchSize,
|
||||
groupTypes: this.props.groupTypes,
|
||||
};
|
||||
if (this.state.lastCursor) {
|
||||
fetchParams.after = this.state.lastCursor;
|
||||
}
|
||||
|
||||
CameraRoll.getPhotos(fetchParams, this._appendAssets, logError);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches more images from the camera roll. If clear is set to true, it will
|
||||
* set the component to its initial state and re-fetch the images.
|
||||
*/
|
||||
fetch: function(clear) {
|
||||
if (!this.state.loadingMore) {
|
||||
this.setState({loadingMore: true}, () => { this._fetch(clear); });
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<ListView
|
||||
renderRow={this._renderRow}
|
||||
renderFooter={this._renderFooterSpinner}
|
||||
onEndReached={this._onEndReached}
|
||||
style={styles.container}
|
||||
dataSource={this.state.dataSource}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
_rowHasChanged: function(r1, r2) {
|
||||
if (r1.length !== r2.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < r1.length; i++) {
|
||||
if (r1[i] !== r2[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_renderFooterSpinner: function() {
|
||||
if (!this.state.noMore) {
|
||||
return <ActivityIndicatorIOS style={styles.spinner} />;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// rowData is an array of images
|
||||
_renderRow: function(rowData, sectionID, rowID) {
|
||||
var images = rowData.map((image) => {
|
||||
if (image === null) {
|
||||
return null;
|
||||
}
|
||||
return this.props.renderImage(image);
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
{images}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_appendAssets: function(data) {
|
||||
var assets = data.edges;
|
||||
var newState = { loadingMore: false };
|
||||
|
||||
if (!data.page_info.has_next_page) {
|
||||
newState.noMore = true;
|
||||
}
|
||||
|
||||
if (assets.length > 0) {
|
||||
newState.lastCursor = data.page_info.end_cursor;
|
||||
newState.assets = this.state.assets.concat(assets);
|
||||
newState.dataSource = this.state.dataSource.cloneWithRows(
|
||||
groupByEveryN(newState.assets, this.props.imagesPerRow)
|
||||
);
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
},
|
||||
|
||||
_onEndReached: function() {
|
||||
if (!this.state.noMore) {
|
||||
this.fetch();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
},
|
||||
url: {
|
||||
fontSize: 9,
|
||||
marginBottom: 14,
|
||||
},
|
||||
image: {
|
||||
margin: 4,
|
||||
},
|
||||
info: {
|
||||
flex: 1,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = CameraRollView;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule GeoLocationExample
|
||||
* @providesModule GeolocationExample
|
||||
*/
|
||||
/* eslint no-console: 0 */
|
||||
'use strict';
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule MapViewExample
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var {
|
||||
MapView,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var MapRegionInput = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
region: React.PropTypes.shape({
|
||||
latitude: React.PropTypes.number,
|
||||
longitude: React.PropTypes.number,
|
||||
latitudeDelta: React.PropTypes.number,
|
||||
longitudeDelta: React.PropTypes.number,
|
||||
}),
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
latitudeDelta: 0,
|
||||
longitudeDelta: 0,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
this.setState(nextProps.region);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var region = this.state;
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.row}>
|
||||
<Text>
|
||||
{'Latitude'}
|
||||
</Text>
|
||||
<TextInput
|
||||
value={'' + region.latitude}
|
||||
style={styles.textInput}
|
||||
onChange={this._onChangeLatitude}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Text>
|
||||
{'Longitude'}
|
||||
</Text>
|
||||
<TextInput
|
||||
value={'' + region.longitude}
|
||||
style={styles.textInput}
|
||||
onChange={this._onChangeLongitude}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Text>
|
||||
{'Latitude delta'}
|
||||
</Text>
|
||||
<TextInput
|
||||
value={'' + region.latitudeDelta}
|
||||
style={styles.textInput}
|
||||
onChange={this._onChangeLatitudeDelta}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Text>
|
||||
{'Longitude delta'}
|
||||
</Text>
|
||||
<TextInput
|
||||
value={'' + region.longitudeDelta}
|
||||
style={styles.textInput}
|
||||
onChange={this._onChangeLongitudeDelta}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.changeButton}>
|
||||
<Text onPress={this._change}>
|
||||
{'Change'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_onChangeLatitude: function(e) {
|
||||
this.setState({latitude: parseFloat(e.nativeEvent.text)});
|
||||
},
|
||||
|
||||
_onChangeLongitude: function(e) {
|
||||
this.setState({longitude: parseFloat(e.nativeEvent.text)});
|
||||
},
|
||||
|
||||
_onChangeLatitudeDelta: function(e) {
|
||||
this.setState({latitudeDelta: parseFloat(e.nativeEvent.text)});
|
||||
},
|
||||
|
||||
_onChangeLongitudeDelta: function(e) {
|
||||
this.setState({longitudeDelta: parseFloat(e.nativeEvent.text)});
|
||||
},
|
||||
|
||||
_change: function() {
|
||||
this.props.onChange(this.state);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var MapViewExample = React.createClass({
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
mapRegion: null,
|
||||
mapRegionInput: null,
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<MapView
|
||||
style={styles.map}
|
||||
onRegionChange={this._onRegionChanged}
|
||||
region={this.state.mapRegion}
|
||||
/>
|
||||
<MapRegionInput
|
||||
onChange={this._onRegionInputChanged}
|
||||
region={this.state.mapRegionInput}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
_onRegionChanged(region) {
|
||||
this.setState({mapRegionInput: region});
|
||||
},
|
||||
|
||||
_onRegionInputChanged(region) {
|
||||
this.setState({
|
||||
mapRegion: region,
|
||||
mapRegionInput: region,
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
map: {
|
||||
height: 150,
|
||||
margin: 10,
|
||||
borderWidth: 1,
|
||||
borderColor: '#000000',
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
textInput: {
|
||||
width: 150,
|
||||
height: 20,
|
||||
borderWidth: 0.5,
|
||||
borderColor: '#aaaaaa',
|
||||
fontSize: 13,
|
||||
padding: 4,
|
||||
},
|
||||
changeButton: {
|
||||
alignSelf: 'center',
|
||||
marginTop: 5,
|
||||
padding: 3,
|
||||
borderWidth: 0.5,
|
||||
borderColor: '#777777',
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<MapView>';
|
||||
exports.description = 'Base component to display maps';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Map',
|
||||
render() { return <MapViewExample />; }
|
||||
},
|
||||
{
|
||||
title: 'Map shows user location',
|
||||
render() {
|
||||
return <MapView style={styles.map} showsUserLocation={true} />;
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule PickerExample
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
PickerIOS,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var PickerItemIOS = PickerIOS.Item;
|
||||
|
||||
var CAR_MAKES_AND_MODELS = {
|
||||
amc: {
|
||||
name: 'AMC',
|
||||
models: ['AMX', 'Concord', 'Eagle', 'Gremlin', 'Matador', 'Pacer'],
|
||||
},
|
||||
alfa: {
|
||||
name: 'Alfa-Romeo',
|
||||
models: ['159', '4C', 'Alfasud', 'Brera', 'GTV6', 'Giulia', 'MiTo', 'Spider'],
|
||||
},
|
||||
aston: {
|
||||
name: 'Aston Martin',
|
||||
models: ['DB5', 'DB9', 'DBS', 'Rapide', 'Vanquish', 'Vantage'],
|
||||
},
|
||||
audi: {
|
||||
name: 'Audi',
|
||||
models: ['90', '4000', '5000', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'Q5', 'Q7'],
|
||||
},
|
||||
austin: {
|
||||
name: 'Austin',
|
||||
models: ['America', 'Maestro', 'Maxi', 'Mini', 'Montego', 'Princess'],
|
||||
},
|
||||
borgward: {
|
||||
name: 'Borgward',
|
||||
models: ['Hansa', 'Isabella', 'P100'],
|
||||
},
|
||||
buick: {
|
||||
name: 'Buick',
|
||||
models: ['Electra', 'LaCrosse', 'LeSabre', 'Park Avenue', 'Regal',
|
||||
'Roadmaster', 'Skylark'],
|
||||
},
|
||||
cadillac: {
|
||||
name: 'Cadillac',
|
||||
models: ['Catera', 'Cimarron', 'Eldorado', 'Fleetwood', 'Sedan de Ville'],
|
||||
},
|
||||
chevrolet: {
|
||||
name: 'Chevrolet',
|
||||
models: ['Astro', 'Aveo', 'Bel Air', 'Captiva', 'Cavalier', 'Chevelle',
|
||||
'Corvair', 'Corvette', 'Cruze', 'Nova', 'SS', 'Vega', 'Volt'],
|
||||
},
|
||||
};
|
||||
|
||||
var PickerExample = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
carMake: 'cadillac',
|
||||
modelIndex: 3,
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var make = CAR_MAKES_AND_MODELS[this.state.carMake];
|
||||
var selectionString = make.name + ' ' + make.models[this.state.modelIndex];
|
||||
return (
|
||||
<View>
|
||||
<Text>Please choose a make for your car:</Text>
|
||||
<PickerIOS
|
||||
selectedValue={this.state.carMake}
|
||||
onValueChange={(carMake) => this.setState({carMake, modelIndex: 0})}>
|
||||
{Object.keys(CAR_MAKES_AND_MODELS).map((carMake) => (
|
||||
<PickerItemIOS
|
||||
key={carMake}
|
||||
value={carMake}
|
||||
label={CAR_MAKES_AND_MODELS[carMake].name}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</PickerIOS>
|
||||
<Text>Please choose a model of {make.name}:</Text>
|
||||
<PickerIOS
|
||||
selectedValue={this.state.modelIndex}
|
||||
key={this.state.carMake}
|
||||
onValueChange={(modelIndex) => this.setState({modelIndex})}>
|
||||
{CAR_MAKES_AND_MODELS[this.state.carMake].models.map(
|
||||
(modelName, modelIndex) => (
|
||||
<PickerItemIOS
|
||||
key={this.state.carmake + '_' + modelIndex}
|
||||
value={modelIndex}
|
||||
label={modelName}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</PickerIOS>
|
||||
<Text>You selected: {selectionString}</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = '<PickerIOS>';
|
||||
exports.description = 'Render lists of selectable options with UIPickerView.';
|
||||
exports.examples = [
|
||||
{
|
||||
title: '<PickerIOS>',
|
||||
render: function() {
|
||||
return <PickerExample />;
|
||||
},
|
||||
}];
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
004D28A31AAF61C70097A701 /* UIExplorerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 004D28A21AAF61C70097A701 /* UIExplorerTests.m */; };
|
||||
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; };
|
||||
134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; };
|
||||
134180021AA9153C003F314A /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FFF1AA91531003F314A /* libReactKit.a */; };
|
||||
@@ -16,9 +17,17 @@
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
832C81C71AAF73C5007FA2F7 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
004D28A41AAF61C70097A701 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||
remoteInfo = UIExplorer;
|
||||
};
|
||||
13417FE71AA91428003F314A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
|
||||
@@ -54,9 +63,19 @@
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTGeolocation;
|
||||
};
|
||||
832C81A51AAF6EFF007FA2F7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
|
||||
remoteInfo = RCTAdSupport;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
004D289E1AAF61C70097A701 /* UIExplorerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
004D28A11AAF61C70097A701 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
004D28A21AAF61C70097A701 /* UIExplorerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIExplorerTests.m; sourceTree = "<group>"; };
|
||||
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; };
|
||||
@@ -69,13 +88,22 @@
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
004D289B1AAF61C70097A701 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
832C81C71AAF73C5007FA2F7 /* libRCTAdSupport.a in Frameworks */,
|
||||
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */,
|
||||
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */,
|
||||
134180011AA9153C003F314A /* libRCTText.a in Frameworks */,
|
||||
@@ -87,14 +115,32 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
004D289F1AAF61C70097A701 /* UIExplorerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
004D28A21AAF61C70097A701 /* UIExplorerTests.m */,
|
||||
004D28A01AAF61C70097A701 /* Supporting Files */,
|
||||
);
|
||||
path = UIExplorerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
004D28A01AAF61C70097A701 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
004D28A11AAF61C70097A701 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1316A21D1AA397F400C0188E /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
|
||||
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
|
||||
832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */,
|
||||
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
|
||||
13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
|
||||
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
|
||||
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
|
||||
13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -152,11 +198,20 @@
|
||||
name = UIExplorer;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832C81A21AAF6EFE007FA2F7 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* UIExplorer */,
|
||||
1316A21D1AA397F400C0188E /* Libraries */,
|
||||
004D289F1AAF61C70097A701 /* UIExplorerTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -165,6 +220,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* UIExplorer.app */,
|
||||
004D289E1AAF61C70097A701 /* UIExplorerTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -172,6 +228,24 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
004D289D1AAF61C70097A701 /* UIExplorerTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 004D28AD1AAF61C70097A701 /* Build configuration list for PBXNativeTarget "UIExplorerTests" */;
|
||||
buildPhases = (
|
||||
004D289A1AAF61C70097A701 /* Sources */,
|
||||
004D289B1AAF61C70097A701 /* Frameworks */,
|
||||
004D289C1AAF61C70097A701 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
004D28A51AAF61C70097A701 /* PBXTargetDependency */,
|
||||
);
|
||||
name = UIExplorerTests;
|
||||
productName = UIExplorerTests;
|
||||
productReference = 004D289E1AAF61C70097A701 /* UIExplorerTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
13B07F861A680F5B00A75B9A /* UIExplorer */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "UIExplorer" */;
|
||||
@@ -197,6 +271,12 @@
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
004D289D1AAF61C70097A701 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "UIExplorer" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@@ -210,6 +290,10 @@
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 832C81A21AAF6EFE007FA2F7 /* Products */;
|
||||
ProjectRef = 832C81A11AAF6EFE007FA2F7 /* RCTAdSupport.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 134A8A211AACED6A00945AAE /* Products */;
|
||||
ProjectRef = 134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */;
|
||||
@@ -234,6 +318,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* UIExplorer */,
|
||||
004D289D1AAF61C70097A701 /* UIExplorerTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -274,9 +359,23 @@
|
||||
remoteRef = 134A8A241AACED6A00945AAE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832C81A61AAF6EFF007FA2F7 /* libRCTAdSupport.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTAdSupport.a;
|
||||
remoteRef = 832C81A51AAF6EFF007FA2F7 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
004D289C1AAF61C70097A701 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -289,6 +388,14 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
004D289A1AAF61C70097A701 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
004D28A31AAF61C70097A701 /* UIExplorerTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -300,6 +407,14 @@
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
004D28A51AAF61C70097A701 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 13B07F861A680F5B00A75B9A /* UIExplorer */;
|
||||
targetProxy = 004D28A41AAF61C70097A701 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
@@ -312,6 +427,42 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
004D28A61AAF61C70097A701 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = UIExplorerTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UIExplorer.app/UIExplorer";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
004D28A71AAF61C70097A701 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = UIExplorerTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UIExplorer.app/UIExplorer";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -435,6 +586,15 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
004D28AD1AAF61C70097A701 /* Build configuration list for PBXNativeTarget "UIExplorerTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
004D28A61AAF61C70097A701 /* Debug */,
|
||||
004D28A71AAF61C70097A701 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "UIExplorer" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -20,6 +20,20 @@
|
||||
ReferencedContainer = "container:UIExplorer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "004D289D1AAF61C70097A701"
|
||||
BuildableName = "UIExplorerTests.xctest"
|
||||
BlueprintName = "UIExplorerTests"
|
||||
ReferencedContainer = "container:UIExplorer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
@@ -28,6 +42,16 @@
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "004D289D1AAF61C70097A701"
|
||||
BuildableName = "UIExplorerTests.xctest"
|
||||
BlueprintName = "UIExplorerTests"
|
||||
ReferencedContainer = "container:UIExplorer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
||||
@@ -31,11 +31,15 @@ var EXAMPLES = [
|
||||
require('./TouchableExample'),
|
||||
require('./ActivityIndicatorExample'),
|
||||
require('./ScrollViewExample'),
|
||||
require('./PickerExample'),
|
||||
require('./DatePickerExample'),
|
||||
require('./GeoLocationExample'),
|
||||
require('./GeolocationExample'),
|
||||
require('./TabBarExample'),
|
||||
require('./SwitchExample'),
|
||||
require('./SliderExample'),
|
||||
require('./CameraRollExample.ios'),
|
||||
require('./MapViewExample'),
|
||||
require('./AdSupportIOSExample'),
|
||||
];
|
||||
|
||||
var UIExplorerList = React.createClass({
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#define TIMEOUT_SECONDS 30
|
||||
|
||||
@interface UIExplorerTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIExplorerTests
|
||||
|
||||
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
|
||||
{
|
||||
if (test(view)) {
|
||||
return YES;
|
||||
}
|
||||
for (UIView *subview in [view subviews]) {
|
||||
if ([self findSubviewInView:subview matching:test]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)testRootViewLoadsAndRenders {
|
||||
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||
BOOL foundElement = NO;
|
||||
|
||||
while ([date timeIntervalSinceNow] > 0 && !foundElement) {
|
||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date];
|
||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date];
|
||||
|
||||
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
|
||||
if ([view respondsToSelector:@selector(attributedText)]) {
|
||||
NSString *text = [(id)view attributedText].string;
|
||||
if ([text isEqualToString:@"<View>"]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
}
|
||||
|
||||
XCTAssertTrue(foundElement, @"Cound't find element with '<View>' text in %d seconds", TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user