As stated in this Tutorial, it would be easy to add a local stored image to an TabItem (or whatever component):
Add the image in XCode to the images.xcassets
Require it like so "icon={require('image!pencil')}" (Name of the image is "pencil")
What i get then is an exception in iOS-Simulator with the following text:
Requiring unknown module "image!pencil". If you are sure the module is
there, try restarting the packager
What is wrong here? The Tutorial? Or has react native changed complete?
The code:
class devdactic_tabs extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'welcome'
};
}
render() {
return (
<TabBarIOS selectedTab={this.state.selectedTab}>
<TabBarIOS.Item
selected={this.state.selectedTab === 'welcome'}
icon={require('image!pencil')}
onPress={() => {
this.setState({
selectedTab: 'welcome',
});
}}>
<Welcome/>
</TabBarIOS.Item>
<TabBarIOS.Item
selected={this.state.selectedTab === 'more'}
systemIcon="contacts"
onPress={() => {
this.setState({
selectedTab: 'more',
});
}}>
<More/>
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
The filenames has to be exactly the same as the resource name in images.xcassets.
For example, when you add a new image set named "foobar", all images assigned to this set has to be named as "foobar.png".
If you're using e.g. Glyphishpro-Images, the image files are prefixed with a number. If you then rename these images to the name without that number, you will get exactly this error!
I ran into this issue last days... Is it yours too?
Please follow an official tutorial on how to add resources into iOS and Android projects.
Also make sure:
NOTE: App build required for new resources
Any time you add a new resource to Images.xcassets you will need to re-build your app through Xcode before you can use it - a reload from within the simulator is not enough.
Related
In my react native app i am showing several images in <Image> tags and i load those images from local folder.
<Image source={require('./src/images/image1.jpg')} />
I want to save image when the user tapped on it.
I can get which image user tapped and pass it to the function. But i put a single image path to it.
_onPressButton(imgName) {
CameraRoll.saveToCameraRoll( './src/images/image1.jpg' , 'photo').then(function(result) {
alert(result);
}).catch(function(error) {
alert(error);
});
}
But this gives me an error in iOS emulator saying it cant find the image in the path.
When i give as,
CameraRoll.saveToCameraRoll( 'https://i.imgur.com/JnrwMpZ.jpg' , 'photo')
It works.
But i want to save these files in my src/images folder.
How can i get a path of this image file OR get this done..?
I appreciate any help regarding this.
Thanks
Here is my solution with Expo, worked in android and should work on ios too
onSave = async () => {
const asset = Asset.fromModule(require('./src/images/image1.jpg'))
if (!asset.localUri) {
await asset.downloadAsync();
}
const uri = asset.localUri;
CameraRoll.saveToCameraRoll(uri, 'photo')
}
This isn't exactly a critical bug, but I always feel weird shaking phones at my desk at work, even more so when it doesn't work first time. If we start talking about shaking iPad Pros, it just feels wrong.
On Android, I can run the following command: adb shell input keyevent KEYCODE_MENU
Is there an iOS equivalent?
Thanks
Sadly no.
You can vote for it on Canny here. Until then, your best bet for iOS is to use a workaround such as one of the ones suggested from the original Github issue. For example, creating your own multi-touch shortcut for opening the dev menu as seen here. It's not ideal but it should work. (code copy pasted below)
import React from 'react';
import {
View,
PanResponder,
NativeModules,
} from 'react-native';
const DevMenuTrigger = ({children}) => {
const {DevMenu} = NativeModules;
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => {
if (gestureState.numberActiveTouches === 3) {
DevMenu.show();
}
},
});
return <View style={{flex: 1}} {...panResponder.panHandlers}>{children}</View>;
};
...
AppRegistry.registerComponent('myApp', (): any => <DevMenuTrigger><MyApp></DevMenuTrigger>
How do I know what native props are available for a component to use setNativeProps. In this example, the <TextInput> component doesn't have text as a prop but apparently setNativeProps use text instead of value as a prop. Thank you!
clearText = () => {
this._textInput.setNativeProps({text: ''});
}
render() {
return (
<View style={{flex: 1}}>
<TextInput
ref={component => this._textInput = component}
/>
<TouchableOpacity onPress={this.clearText}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
}
This is pretty common in react-native, due to limited documentation. Whenever looking for any information regarding react-native components, it is a good idea to simply look at the .js file you are using. In this case, TextInput, can be found...
Project/node_modules/react-native/Libraries/Components/TextInput/TextInput.js
Hope you can find what you're looking for - with a bit of digging. If you want to look further, looking into the RCT files is a good idea also.
Project/node_modules/react-native/Libraries/Text/RCTTextField.h
Project/node_modules/react-native/Libraries/Text/RCTTextView.h
I am building an app that lets the user download a PDF file when he clicks on a button.
I use the library react-native-fetch-blob for this purpose.
It works well on Android.
On iOS, the console log tells me the download has worked well, but:
I don't see anything happening on screen (on Android, there is a notification that tells me the download is complete)
I cannot find the file anywhere on the iPad. There is no "My files" folder or equivalent.
What is the right way to achieve what I want?
The solution thats worked for me in iOS was use RNFetchBlob.ios.openDocument function inside the then of fetch. This function open the file on the device file explorer where you have the option to download. Here is the code example:
downloadPDFiOS (uri) {
let uriSplitted = uri.split("/");
const fileName = uriSplitted.pop();
const dirs = RNFetchBlob.fs.dirs;
RNFetchBlob
.config({
path: dirs.DocumentDir + '/' + fileName,
fileCache: true,
})
.fetch('GET', uri, {
//some headers ..
})
.then((res) => {
RNFetchBlob.ios.openDocument(res.data);
})
.catch((e) => {
console.log('Error en el fetch: ', e);
})
}
I'm trying to create a component using React Native like so:
export class IndicatorOverlay extends Component {
render() {
return (
<View>
<Text>text</Text>
</View>
);
}
};
The above works, but when I try to make it stateless like so...
export default ({ text = 'text' }) => {
return (
<View>
<Text>{text}</Text>
</View>
);
};
I get the following error:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined. You
likely forgot to export your component from the file it's defined in.
I'm sure I'm missing something basic, but I just can't see it. I use a similar stateless component in a React web app and it's fine.
Using react 16.0.0-alpha.6 and react-native 0.43.2, and am seeing this error in the iPhone simulator.
Hope someone can help :)
This is likely because the first example is a named export, while the second one is a default one therefore the way need to import them is different.
Assuming you import your module like this:
import { IndicatorOverlay } from 'IndicatorOverlay';
you have two options. Either:
1) change the way you import your module (since the stateless component is a default export now):
import IndicatorOverlay from 'IndicatorOverlay';
2) keep the import intact, but refactor your stateless component to something like this:
export const IndicatorOverlay = ({text = 'text'}) => {
return (
<View>
<Text>{text}</Text>
</View>
);
};
You can make it more DRY btw:
export const IndicatorOverlay = ({ text = 'text' }) => (
<View>
<Text>{text}</Text>
</View>
);
You can read more about imports and exports on MDN:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export