How can I achieve the "View slide-in" effect in react native? - ios

I am currently working on my very first react-native application and am wondering how that slide in effect of a new view can be achieved and where that "hidden" view should be placed.
My Application is currently build like this:
<View style={{flex:1}}>
<View style={{flex:.8, justifyContent:'center'}}>
.. some login Form
</View>
<View style={{flex:.2, justifyContent:'center', alignItems:'center'}}>
<TouchableHighlight onPress={this._toggleRegistryView}>
<Text> or register here </Text>
</TouchableHighlight>
</View>
</View>
As you can see in this basic code I want to slide-in the Registration View as soon as the touchable component is pressed.
Do I need to store the view "invisible" with a width of 0 and height of 100% on one side and then animate it to the full device width?
Right now I have no idea besides a whole new view render when the state changes
render(){
return({this.state.view == 'login' ? <LoginView /> : <RegistryView />});
}
Unfortunately this triggers a "hard" view change and not a smooth right to left or left to right animation where the view slides in.
If my question was unclear please inform me - I'll gladly try to specify it :) Thank you for your help

You should split your application into multiple scenes (screens) and use the Navigator component to transition between the scenes.
Here is a tutorial from the TaskRabbit blog to get you started.
Once you have you scenes set up, you can experiment with different SceneConfigs for different types of transition animations.

A transition from a page to another is nothing else but navigation.
In order to navigate from a page to another in React Native, you will want a navigation library.
The default Navigator component from React Native might work, but it's got a lot of limitations and issues, and the default solution most people turn to (and which after 3yrs of RN I strongly recommend), is React Navigation. If you are using Expo, it also ships by default, so you can jump right into it, and define your screens like so:
import React from 'react';
import { View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator({
Login: {
screen: LoginView,
},
Register: {
screen: RegisterView,
},
});
export default createAppContainer(AppNavigator);
If not, here's a quick start guid to using it outside of Expo.

Related

react-native-webview doesn't change screen orientation on iOS

I'm working on a small react-native app. It's nearly only a container for showing my webapp, so nearly everthing is running cool.
The problem is, the user needs to rotate the screen on some of the webapp-sites. With my implementation this works very good on android, but not on iOS. The funny thing is, when I start the app on iOS via EXPO GO, it also works.
I've searched a lot but I can not find a solution for this. Do you have any idea how to change that behavior on iOS?
This is my App.js
import React from "react";
import { StyleSheet, View } from "react-native";
import WebView from 'react-native-webview';
const WEBSITE = 'https://www.google.com'
export default function App() {
return (
<View style={styles.container}>
<View style={{ width: '100%', height: '100%' }}>
<WebView
source={{ uri: WEBSITE }}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "flex-start",
alignItems: "flex-start",
},
});
I would first check your xcode project settings and ensure that the orientations you are looking for are enabled. If you open up xcode and check the orientations you should have all the orientations selected that you want to support. The project below has only portrait enabled therefore I'd suggest you enable the landscape orientations and hopefully this should resolve your problem.

React Native/Expo: Modal not showing when 'visible' prop is true on iOS

I have an app that I've built in React Native where I have a modal that will appear when a button is pressed and prompts the user for input. I've made other modals in the app that work fine using the same method that I am using now. But when I change the state for this modal that determines whether the modal is visible, it seems to completely ignore it and does not display. The modal works on my android and on my many android emulators but it does not work on my iphone 10 for some reason.
I have a file GameScreen.js that is the screen component and holds the modal within it. It also holds the relevant methods and state for the modal's visibility:
import {
Body,
Button,
Container,
Content,
Header,
Icon,
Left,
Right,
View } from 'native-base';
import { BackHandler, StyleSheet, Text, TextInput, TouchableOpacity, Platform } from 'react-native';
import React, { Component, createRef } from 'react';
import myModal from '../components/myModal';
export default class GameScreen extends Component {
constructor(props) {
super(props)
this.state = {
// other state
isVisible: false,
}
this.displayModal = this.displayModal.bind(this);
}
displayModal(show) {
this.setState({
isVisible: show
})
}
render() {
return (
<Container>
<myModal
displayModal={this.displayModal}
isVisible={this.state.isVisible}
/>
<View>
<TouchableOpacity
style={styles.button}
onPress{() => this.displayModal(true)} >
<Image />
</TouchableOpacity>
</View>
</Container>
)
}
}
I have the modal in its own file and it looks like this (myModal.js):
import {
Button,
Card,
CardItem,
Container,
Text,
View } from 'native-base';
import { Modal, StyleSheet } from 'react-native';
import React, { Component } from 'react';
export default class myModal extends Component {
render() {
return (
<Container>
<Modal
transparent
animationType='fade'
visible={this.props.isVisible}
onRequestClose={() => this.props.displayModal(false)}
>
<View>
// My view stuff
</View>
</Modal>
</Container>
)
}
}
I have tried putting console logs in the modal file to see if the state is actually changing and it does seem to be. I've added a log of the isVisible state in render() and in a componentDidUpdate() and it always logs out true once I have pressed the button in GameScreen but it seems like the modal is ignoring it. When I manually change the 'visible' prop to true it displays fine so it's not as if it has a problem with what I want to render.
I've also tried to run expo in production mode as some people have cited issues with dev mode and react native modals. I started the metro bundler with 'expo start --no-dev --minify' as the expo docs suggest but the problem persists.
As I said above, this exact approach is working fine in other parts of the app but seems to not like the GameScreen for some reason. And, this problem ONLY happens on iOS. I don't have any other iphones and don't have an access to a mac for xCode so I guess it might be the phone itself but it renders the other modals I have on my app just fine. I've been banging my head on the keyboard trying to get this weird bug figured out for a while, so thank you for any responses!!
So I just now figured it out and it was a dumb solution that I hope will help someone else. Thank you #Kamal Hossain, your suggestion helped me diagnose the problem.
So in my GameScreen, I was using an API called react-native-actions-sheet which is this nice little drawer UI component which held the button that was trying to open the modal. The button also closed the drawer after it was pressed. The button was interacting with the state just fine, but I think the process of closing the drawer was messing with the modal rendering somehow.
My working solution is to make the button wait for a fraction of a second before attempting to open the modal on ios and it works just fine now:
<TouchableOpacity
onPress={() => {
// closes drawer
this.props.toggleActionSheetVisibility();
// waits if on ios and then opens modal
setTimeout(() => this.displayModal(true), Platform.OS === "ios" ? 200 : 0);
}}
/>
I don't know why it was only happening on ios specifically but I hope this helps someone in the future.

iOS Header overlaps layout for Iphone 11

I've got a react native app -> I've currently noticed that the text on my screen overlaps on iphone 10+ devices. How would I create a safearea for the new devices?
I've tried to add a tag to wrap my stack.navigator for the home screen but had no luck so far.
Is this something I would target on my react native or in xcode?
enter image description here
use
import { SafeAreaView } from 'react-native';
to handle safe area I have shown in below code how to handle safe area for iPhone 10 plus device
in below code I have divided the safe area in two-part one is for top safe area and another is the bottom safe area and you place your all component in bottom safe area
render() {
return (
<View style={{flex: 1} >
<SafeAreaView style={{flex: 0}} />
<SafeAreaView style={{flex: 1}}>
//here you can place your component
</SafeAreaView>
</View>
)
}

Handling the status bar on iOS

Is there a goto way to handle the status bar on iOS? For my app, I just want everything to be below the status bar.. but it looks like the only way to do that is to go to every single component and add padding? I would guess theres a way to do it in xcode but I have no clue!
Thanks!
There is already a component in react-native for the StatusBar
You just need to add it as
<YourParentWrapper style={{flex: 1}}>
<View style={{ height, backgroundColor }}>
<StatusBar { ...props } />
</View>
// ... Your navigation or the child components
</YourParentWrapper>
where the height is
Platform.OS === 'ios' ? 20 : StatusBar.currentHeight
This will handle your components below the default status bar for all the devices

React Native: How to make a view stick on screen while the screen changes?

I'm building a podcasting app with react native and I would like to implement the mini player you see at bottom of screen in most podcasting/music apps. See image below. I want to make the mini player stick no matter which screen you navigate to. Any idea how to implement this in react native? I'm using react navigation as the main navigator right now https://reactnavigation.org/.
The best way to do this is use the magic of flexbox.
Think about your app as combination of two major screens.
1) The part with header, navigation menus and the playlist (inside etc.)
2) The player
Try this layout
<View style={styles.container}>
<View style={styles.firstBox}>
1)
</View>
<View style={styles.secondBox}>
2)
</View>
</View>
Now all you have to do is assign proper styles
const styles = {
container: {
flex: 1,
},
firstBox: {
flex: 8
},
secondBox: {
flex: 2
}
}
This is enough for the basic structure. You can design accordingly.

Resources