Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NavigatorIOS] doesn't update when navigationBarHidden changes #846

Closed
ustun opened this issue Apr 14, 2015 · 34 comments
Closed

[NavigatorIOS] doesn't update when navigationBarHidden changes #846

ustun opened this issue Apr 14, 2015 · 34 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@ustun
Copy link

ustun commented Apr 14, 2015

On my main view, I want to hide navigation bar, but show it in the child views. I pass some props to show/hide the navbar to children, and call them accordingly in componentDidMount/ componentWillUnmount.

Showing works, but hiding doesn't work (or sometimes works, sometimes doesn't).

I have also tested whether it works reliably when just setting it on/off in a single view and it doesn't seem to work. Here is a gist: https://gist.github.com/ustun/5670b7480569fbb784a4

@ericzwong
Copy link

i have sample problem with u , and when i change the tarbar, the navigationbar title can't change

@MandarinConLaBarba
Copy link

I'm also having this issue.

@kujohn
Copy link
Contributor

kujohn commented Apr 26, 2015

Having this issue as well. Tried to follow the chain that lead to this. This method does get called on state change or on navigator.replace and navgiation.resetTo, but it stops there.

Perhaps the UIKit portion isn't setup for accepting the changes? https://github.com/facebook/react-native/blob/master/React/Views/RCTWrapperViewController.m#L69

@kujohn
Copy link
Contributor

kujohn commented Apr 26, 2015

Perhaps the work around for now is to setup the first page as non-navigatorIOS page, and the child views to start navigatorIOS routes. You'll loose the swipe back to first page though.

@jeroenbourgois
Copy link

Any more insights on this? I just reverted a lot of code since I was using the 'navigatorIOS' from the second page forward. But then I saw the navigationBarHidden prop and thought it would solve my setup. But I was wrong :)

@liubko
Copy link
Contributor

liubko commented May 19, 2015

navigationBarHidden works properly when I use navigator.push, but it doesn't work when I use navigator.replace or navigator.resetTo

@jeroenbourgois
Copy link

@liubko I cannot get that to work. Can you show the code you use to change navigationBarHidden when using navigator.push?

Here is how I do it, with no effect (btw navigationBarHidden was set to false when setting up the NavigatorIOS component):

 this.props.navigator.push({
   component: Login,
   title: "Sign In",
   navigationBarHidden: false, // try it here
 })

 this.props.navigator.navigationBarHidden = false // and here

@nicinabox
Copy link
Contributor

@jeroenbourgois navigationBarHidden is a prop on NavigatorIOS itself. Passing it in push won't work because those are options for the route. I'm not sure about setting it like this.props.navigator.navigationBarHidden = false.

@liubko
Copy link
Contributor

liubko commented May 19, 2015

@jeroenbourgois I save isNavBarHidden status in parent component state.

<NavigatorIOS navigationBarHidden={this.state.isNavBarHidden}
              ref="nav"
              initialRoute={{...}}  />

so then if I do smth like this:

this.refs.nav.push({...});
this.setState({
  isNavBarHidden: ...
});

it works correctly. But it doesn't work when I use replace or resetTo

@jeroenbourgois
Copy link

AHA but of course! Should have seen that.... thanks a bunch!

@eltoob
Copy link

eltoob commented May 27, 2015

Still not quite clear how to change isNavBarHidden from a child view .... @liubko how does this.setState is going to fix the problem as the state is at the parent level class

@liubko
Copy link
Contributor

liubko commented May 27, 2015

@eltoob when you change state in parent component you then pass it to NavigatorIOS

<NavigatorIOS navigationBarHidden={this.state.isNavBarHidden} />

this will cause a re-render with new navigationBarHidden value

@alexrabarts
Copy link

@liubko are you passing the context of the parent component to the child component through the props object?

@liubko
Copy link
Contributor

liubko commented May 27, 2015

@alexrabarts you can pass a callback which will change state in parent component
If you are using flux you could trigger some action to update store's isNavBarHidden value, and you will need to listen for that store in parent component.

Actually I ended up using my own header component, to have more control on it

@eltoob
Copy link

eltoob commented May 27, 2015

@liubko just a bit confused ... how do you change the state of the NavigatorIOS from a child component ... it doesn't inherit the state from the parent component

@liubko
Copy link
Contributor

liubko commented May 27, 2015

@eltoob not sure if we understand each other, I made a demo: https://rnplay.org/plays/L9v2wg

@brentvatne
Copy link
Collaborator

@liubko - great way to demo that 😄

@brentvatne brentvatne changed the title NavigatorIOS doesn't update when navigationBarHidden changes [NavigatorIOS] doesn't update when navigationBarHidden changes May 31, 2015
@brentvatne
Copy link
Collaborator

I fixed this here: brentvatne/react-native-navigator-ios-hide-bugfix@e0655d1

If this doesn't seem like too much of a hack, I can follow along those lines and have it update other props as well.

cc @ide

@shahbhavir
Copy link

@brentvatne your fix would work when I move from A(no navbar)->B(no navbar)->C(with navbar). But when I move back to B from C, B will show navbar and toggle in B won't work.

Is there any way we can listen on navigator route change? This would fix the problem.

@marcshilling
Copy link

Yeah like @shahbhavir said, this is all good for pushing new views, but does not take into account going backwards.

I need view A (nav bar hidden) to push view B (with nav bar). And then be able to tap back and have the nav bar removed again.

Also take into account supporting the interactive pops by dragging edge of the screen.

In iOS world this is as simple as [self.navigationController setNavigationBarHidden:YES animated:animated]; in viewWillAppear of view A, and [self.navigationController setNavigationBarHidden:NO animated:animated]; in viewWillAppear of view B, but React Native doesn't have those concepts.

@maplebaby
Copy link

@brentvatne I think it is not solved! Please have a look for my demo -> https://rnplay.org/apps/o8dTnw

@adamterlson
Copy link
Contributor

It is indeed not solved. @shahbhavir has the reason why, and I agree; events for navigation route change would be a straight-forward way to solve this issue.

Has anyone had any luck with a solid solution to hiding the nav bar on the home page (no matter how it's navigated to)?

@brentvatne
Copy link
Collaborator

Pull request for this is welcome! Nobody is currently working on NavigatorIOS, so if you use it then you're as good a person as anyone to make it better 😄

@bogdantmm92
Copy link

+1

@aisk
Copy link

aisk commented Jul 26, 2015

I updated to react native 0.8 and still have this problem, wish it could be fixed.

@sonthonaxrk
Copy link

The RCTNavigatorItem is wrapped in a little utility class called StaticContainer which prevents the updated state from updating the RCTNavigatorItem.

  <StaticContainer shouldUpdate={shouldRecurseToNavigator}>
    <NavigatorTransitionerIOS
      ref={TRANSITIONER_REF}
      style={styles.transitioner}
      vertical={this.props.vertical}
      requestedTopOfStack={this.state.requestedTopOfStack}
      onNavigationComplete={this.handleNavigationComplete}>
      {items}
    </NavigatorTransitionerIOS>
  </StaticContainer>

https://github.com/facebook/react-native/blob/master/Libraries/Components/Navigation/NavigatorIOS.ios.js#L643-L652

@brentvatne

Your demo here brentvatne/react-native-navigator-ios-hide-bugfix@e0655d1 works fine as long as you're pushing the view. Popping doesn't trigger an update.

Now I'm not recommending that anyone do thism but setting getting rid of the StaticContainer or setting shouldUpdate={true}, allows the modification of the state to whatever is passing in navigationBarHidden to the NavigationBarIOS to work.

sonthonaxrk@e5374d2#diff-2cc53d7b47c5b24c6942b6b1aec85b40


Perhaps we should look at the logic of how shouldUpdateChild in routeToStackItem is calculated https://github.com/facebook/react-native/blob/master/Libraries/Components/Navigation/NavigatorIOS.ios.js#L592

@katrinanova
Copy link
Contributor

To hide navigationBar in any chosen view you can change one line in source code.
Then you will be able to pass navigationBarHidden: true directly to any route object.

In node_modules/react-native/Libraries/Components/Navigation/NavigatorIOS.ios.js

in

 _routeToStackItem: function(route: Route, i: number) {
    var Component = route.component;
    var shouldUpdateChild = this.state.updatingAllIndicesAtOrBeyond !== null &&
      this.state.updatingAllIndicesAtOrBeyond >= i;

    return (
      <StaticContainer key={'nav' + i} shouldUpdate={shouldUpdateChild}>
        <RCTNavigatorItem
          title={route.title}
          style={[
            styles.stackItem,
            this.props.itemWrapperStyle,
            route.wrapperStyle
          ]}
          backButtonIcon={resolveAssetSource(route.backButtonIcon)}
          backButtonTitle={route.backButtonTitle}
          leftButtonIcon={resolveAssetSource(route.leftButtonIcon)}
          leftButtonTitle={route.leftButtonTitle}
          onNavLeftButtonTap={route.onLeftButtonPress}
          rightButtonIcon={resolveAssetSource(route.rightButtonIcon)}
          rightButtonTitle={route.rightButtonTitle}
          onNavRightButtonTap={route.onRightButtonPress}
          navigationBarHidden={route.navigationBarHidden}
          shadowHidden={this.props.shadowHidden}
          ...

change

navigationBarHidden={this.props.navigationBarHidden}

to

navigationBarHidden={route.navigationBarHidden}

now you can

this.props.navigator.push({ component: YourComponent, navigationBarHidden: true, })

@mixophrygian
Copy link

+1 @katrinanova, this worked for me, thank you!

@brentvatne
Copy link
Collaborator

That's neat @katrinanova :) Want to submit a pull request for this?

@katrinanova
Copy link
Contributor

@brentvatne just submitted a pr :)

@naoisegolden
Copy link

For the record, @katrinanova's PR #5101
Thanks!

@pedro
Copy link

pedro commented Feb 17, 2016

Anyone else still having issues?

I'm still having trouble to update simple props like the navigator title by calling navigator.replace in 0.20.

To test things out I tried removing the StaticContainer or setting shouldUpdate={true} but this gives me an error (when calling replace):

Attempting to remove invalid RCT subview of RCTNavigator

I'll keep checking NavigatorIOS.ios.js and RCTNavItem.m. Any suggestions/insights here are obviously appreciated!

@macavity23
Copy link

@pedro I am still having the same issue in 0.20. Passing navigationBarHidden in replace() or resetTo() does not work, but it does work in push(). I am hacking around this by calling:
push({ navigationBarHidden: false, leftButtonIcon: null, leftButtonTitle: ' ', })

This is not quite a replacement because you still get the push transition, but I'm living with that.

@mkonicek
Copy link
Contributor

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out its new home: https://productpains.com/post/react-native/navigatorios-doesnt-update-when-navigationbarhidden-changes

ProductPains helps the community prioritize the most important issues thanks to its voting feature.
It is easy to use - just login with GitHub. GitHub issues have voting too, nevertheless
Product Pains has been very useful in highlighting the top bugs and feature requests:
https://productpains.com/product/react-native?tab=top

Also, if this issue is a bug, please consider sending a pull request with a fix.
We're a small team and rely on the community for bug fixes of issues that don't affect fb apps.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests