Upgrade to Pro — share decks privately, control downloads, hide ads and more …

It all starts with navigation

It all starts with navigation

For the past 2.5 years I've been working on a bunch of projects, all aiming to expose some native capabilities to be controlled from JavaScript in React Native app. Most notable ones were: native driver support for Animated and two libraries: React Native Gesture Handler and Reanimated. All these projects were inspired by needs of navigation libraries and were meant to fill the gap between platform native navigation solutions and ones that are available in React Native.

Our React Native projects often starts by deciding whether to go with native navigation (react-native-navigation) or JS navigation library (react-navigation). But given all these improvements can we still call react-navigation "not native"? In this talk we will learn how Gesture Handler and Reanimated libraries came to live with navigation being the driving force. In this context I will discuss how far is react-navigation from finally proclaiming the badge of really native navigation library.

Krzysztof Magiera

September 05, 2018
Tweet

More Decks by Krzysztof Magiera

Other Decks in Technology

Transcript

  1. Evolution of navigation 8 16 24 32 40 Presence Months

    from now NavigatorIOS ex-navigator ex-navigation react-navigation react-native-navigation Navigator Experimental Navigator
  2. state = { fade: new Animated.Value(0) }; 1. Create value

    <Animated.View style={{ opacity: this.state.fade }} /> 2. Hook it up as a view attribute Animated.timing( this.state.fade, { toValue: 1, } ).start(); 3. Animate value 4. Or attach it to an event 5. Combine/process values const fade = Animated.multiply( this.state.factor, this.state.scrollY.interpolate({ inputRange: [0, 300], outputRange: [1, 0] }) ); <Animated.ScrollView onScroll={event L> { const yoffset = event.nativeEvent.contentOffset.y; this.state.scrollX.setValue(yoffset); }} > <Animated.ScrollView onScroll={Animated.event([ { // event.nativeEvent.contentOffset.y nativeEvent: { contentOffset: { y: this.state.scrollY } } } ])} > Animated
  3. react-native-navigation Style object format { // Common navBarTextColor: '#000000', //

    change the text color of the title (remembered across pushes) navBarTextFontSize: 18, // change the font size of the title navBarTextFontFamily: 'font-name', // Changes the title font navBarBackgroundColor: '#f7f7f7', // change the background color of the nav bar (remembered across pushes) navBarCustomView: 'example.CustomTopBar', // registered component name navBarComponentAlignment: 'center', // center/fill navBarCustomViewInitialProps: {}, // navBar custom component props navBarButtonColor: '#007aff', // Change color of nav bar buttons (eg. the back button) (remembered across pushes) topBarElevationShadowEnabled: false, // (Android - default: true, iOS - default: false). Disables TopBar elevation shadow on Lolipop and navBarHidden: false, // make the nav bar hidden navBarHideOnScroll: false, // make the nav bar hidden only after the user starts to scroll navBarTranslucent: false, // make the nav bar semi-translucent, works best with drawUnderNavBar:true navBarTransparent: false, // make the nav bar transparent, works best with drawUnderNavBar:true, navBarNoBorder: false, // hide the navigation bar bottom border (hair line). Default false drawUnderNavBar: false, // draw the screen content under the nav bar, works best with navBarTranslucent:true drawUnderTabBar: false, // draw the screen content under the tab bar (the tab bar is always translucent) navBarBlur: false, // blur the entire nav bar, works best with drawUnderNavBar:true tabBarHidden: false, // make the screen content hide the tab bar (remembered across pushes) statusBarHidden: false, // make the status bar hidden regardless of nav bar state statusBarTextColorScheme: 'dark', // text color of status bar, 'dark' / 'light' (remembered across pushes) navBarSubtitleColor: 'red', // subtitle color navBarSubtitleFontFamily: 'font-name', // subtitle font, 'sans-serif-thin' for example navBarSubtitleFontSize: 13, // subtitle font size screenBackgroundColor: 'white', // Default screen color, visible before the actual react view is rendered orientation: 'portrait' // Sets a specific orientation to a modal and all screens pushed to it. Default: 'auto'. Supported values: 'auto' disabledButtonColor: '#ff0000' // chnaged the navigation bar button text color when disabled. rootBackgroundImageName: 'iOS: <name of image in Images.xcassets>. Android: <name of drawable>', // Static while you transition between
  4. Gestures - PanResponder UI Thread JS Thread • Receive hardware

    events • Send to JS • Calculate pan translation • Generate pan event • Handle event & request UI update • Update UI
  5. react-native-gesture-handler Handler Parameters Event attributes Pan minDist, minPointers translationXY, absoluteXY

    Pinch scale, focalXY, velocity Tap numberOfTaps, maxDuration numberOfPointers Rotation rotation, anchorXY, velocity
  6. <RotationGestureHandler onGestureEvent={Animated.event( [{ nativeEvent: { rotation: this.rotationValue } }], {

    useNativeDriver: true } )} > <Animated.View style={animatedTransforms} /> </RotationGestureHandler>; react-native-gesture-handler
  7. react-navigation • Screen transition animations running on UI Thread –

    nativeDriver / reanimated • Native gestures for back swipe • Gesture-handler backed drawer
  8. Style object format { // Common navBarTextColor: '#000000', // change

    the text color of the title (remembered across pushes) navBarTextFontSize: 18, // change the font size of the title navBarTextFontFamily: 'font-name', // Changes the title font navBarBackgroundColor: '#f7f7f7', // change the background color of the nav bar (remembered across pushes) navBarCustomView: 'example.CustomTopBar', // registered component name navBarComponentAlignment: 'center', // center/fill navBarCustomViewInitialProps: {}, // navBar custom component props navBarButtonColor: '#007aff', // Change color of nav bar buttons (eg. the back button) (remembered across pushes) topBarElevationShadowEnabled: false, // (Android - default: true, iOS - default: false). Disables TopBar elevation shadow on Lolipop and navBarHidden: false, // make the nav bar hidden navBarHideOnScroll: false, // make the nav bar hidden only after the user starts to scroll navBarTranslucent: false, // make the nav bar semi-translucent, works best with drawUnderNavBar:true navBarTransparent: false, // make the nav bar transparent, works best with drawUnderNavBar:true, navBarNoBorder: false, // hide the navigation bar bottom border (hair line). Default false drawUnderNavBar: false, // draw the screen content under the nav bar, works best with navBarTranslucent:true drawUnderTabBar: false, // draw the screen content under the tab bar (the tab bar is always translucent) navBarBlur: false, // blur the entire nav bar, works best with drawUnderNavBar:true tabBarHidden: false, // make the screen content hide the tab bar (remembered across pushes) statusBarHidden: false, // make the status bar hidden regardless of nav bar state statusBarTextColorScheme: 'dark', // text color of status bar, 'dark' / 'light' (remembered across pushes) navBarSubtitleColor: 'red', // subtitle color navBarSubtitleFontFamily: 'font-name', // subtitle font, 'sans-serif-thin' for example navBarSubtitleFontSize: 13, // subtitle font size screenBackgroundColor: 'white', // Default screen color, visible before the actual react view is rendered orientation: 'portrait' // Sets a specific orientation to a modal and all screens pushed to it. Default: 'auto'. Supported values: 'auto' disabledButtonColor: '#ff0000' // chnaged the navigation bar button text color when disabled. rootBackgroundImageName: 'iOS: <name of image in Images.xcassets>. Android: <name of drawable>', // Static while you transition between // iOS only statusBarTextColorSchemeSingleScreen: 'light', // same as statusBarTextColorScheme but does NOT remember across pushes statusBarHideWithNavBar: false, // hide the status bar if the nav bar is also hidden, useful for navBarHidden:true statusBarBlur: false, // blur the area under the status bar, works best with navBarHidden:true disabledBackGesture: false, // default: false. Disable the back gesture (swipe gesture) in order to pop the top screen. disabledSimultaneousGesture: true, // default: true. Disable simultaneous gesture recognition.